Gateway = = > Java design pattern of station B
❤❤❤ Thanks to Shang Silicon Valley ❤❤❤
Recently, I began to plan to learn design patterns. Come on!!!
proxy pattern
Proxy mode: provide a copy to an object, and control the access of the real object through the copy object. Even if you want to expand new content or functions, you can modify them on the copy object
(it can be understood as separation. You can find the ontology through separation. The management operation of separation will affect the ontology.)
The proxied object can be a remote object, an object with high creation cost, or an object requiring security control
It can be divided into three types:
Static proxy
Dynamic agent (JDK agent, interface agent)
Cglib agent (creating objects dynamically in memory)
Static proxy
The proxy object and the target object should implement the same interface, and then call the method of the target object by calling the same method.
Use static proxy mode; The target function can be extended through the proxy object without modifying the function of the target object;
However, because the proxy object needs to implement the same interface as the target object, many proxy classes need to be generated;
If the interface needs to add methods, both the target object and the proxy object need to add method implementations
Case:
Common interface between agent and target UserDao
//Interface, target object and proxy object should be implemented; public interface UserDao { //Add user method; public abstract void addUser(); }
Target RealUserDao
//Objectives; public class RealUserDao implements UserDao{ @Override public void addUser() { System.out.println("The target object says you want to add users"); } }
Proxy ProxyUserDao
//Agency; public class ProxyUserDao implements UserDao{ //Aggregate goals; private UserDao target; public ProxyUserDao(UserDao target) { this.target = target; } @Override public void addUser() { System.out.println("Static proxy start-->"); target.addUser(); System.out.println("end--->"); } }
Impersonate Client
public class Client { public static void main(String[] args) { ProxyUserDao proxyUserDao =new ProxyUserDao(new RealUserDao()); //Call the method to the target object through the proxy object; proxyUserDao.addUser(); } } /* Static proxy start -- > The target object says you want to add users End -- > */
Dynamic agent
Only the target object needs to implement the interface; Proxy objects do not need to implement interfaces
Package of proxy class: java.lang.reflect.Proxy
The proxy object uses the JDK API to dynamically build the proxy object in memory;
When using the method newProxyInstance(),
Parameter: classloader; Specify the class loader used by the current target object;
Parameter: class <? > [] interfaces: the interface implemented by the target object
Parameter: InvocationHandler h) when executing the target object method, the event generator will be triggered, and the executed target object method will be obtained through reflection
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
Interface UserDao
//The interface only needs to be implemented by the target object; public interface UserDao { //Add user method; public abstract void addUser(); }
Target class RealUserDao
//Objectives; public class RealUserDao implements UserDao{ @Override public void addUser() { System.out.println("The target object says you want to add users"); } }
proxy class
//Agent factory; public class ProxyFactory { //Maintain target objects; private Object target; //initialization; public ProxyFactory(Object target) { this.target = target; } //Dynamic agent; public Object getProxyInstance(){ return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Dynamic agent/JDK agent"); Object invoke = method.invoke(target, args); return invoke; } }); } }
Simulation client
public class Client { public static void main(String[] args) { //Create the target object; UserDao realUserDao = new RealUserDao(); //Create a proxy object for the target object; UserDao proxyFactory= (UserDao)new ProxyFactory(realUserDao).getProxyInstance(); proxyFactory.addUser(); } } /* Dynamic agent / JDK agent The target object says you want to add users */
Cglib agent
Cglib agent (subclass agent)
Build a subclass object in memory; Realize the function expansion of the target object
The bottom layer of Cglib package is to convert bytecode and generate new classes by using bytecode processing framework ASM
Note that the class of the proxy cannot be defined as final, or an error is reported: java.lang.IllegalArgumentException:
If the method of the target object is final/static, it will not be intercepted (additional business methods of the target object will not be executed)
maven dependency required;
<!-- https://mvnrepository.com/artifact/cglib/cglib --> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.11</version> </dependency> <!-- https://mvnrepository.com/artifact/org.ow2.asm/asm-commons --> <dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm-commons</artifactId> <version>7.1</version> </dependency>
Class diagram principle
The getInstance () method creates a proxy object for the target object target;
The overridden intercept () method implements the method call to the target object
Target class RealUserDao
//Target class; public class RealUserDao { //Add users; public void addUser(){ System.out.println("Yes Cglib The way,No interface required"); System.out.println("How to add users"); } }
Proxy class ProxyFactory
//Agency; public class ProxyFactory implements MethodInterceptor { //Define the target object; private Object target; //initialization; public ProxyFactory(Object target) { this.target = target; } //Returns the proxy object of target; public Object getProxyInstance(){ //Create a tool class; Enhancer enhancer = new Enhancer(); //Set parent class; enhancer.setSuperclass(target.getClass()); //Set callback function; enhancer.setCallback(this); //Return the proxy object; return enhancer.create(); } //The overridden intercept () method implements the method call to the target object public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("start Cglib proxy pattern"); Object invoke = method.invoke(target, objects); System.out.println("Cglib proxy pattern==> Submit <=="); return invoke; } }
Simulation client
//Simulation client; public class Client { public static void main(String[] args) { //Target object; RealUserDao target =new RealUserDao(); //Get the proxy object of the target object; RealUserDao proxyFactory = (RealUserDao) new ProxyFactory(target).getProxyInstance(); //Method of executing proxy object; proxyFactory.addUser(); } } /* Start Cglib proxy mode Cglib mode is used, and no interface is required How to add users Cglib Proxy mode = = > submit<== */