proxy pattern
1. Agent mode
In Proxy Pattern, one class represents the functions of another class. This type of design pattern belongs to structural pattern.
In proxy mode, we create objects with existing objects to provide functional interfaces to the outside world
1.1 INTRODUCTION
Intention: in an object-oriented system, direct access to some objects will bring a lot of trouble to users or system structure for some reasons (for example, some operations need security control). We can add an access to this object when accessing this object
Main solution: I want to do some control when accessing a class.
How to solve: add an intermediate layer.
Key code: combination of implementation and proxy class.
1.2 application examples
When accessing an object, if you need to authenticate, judge or verify the visitor, you can do some processing before accessing, or if you need to print a process log, you can add a log during the access process to facilitate judgment. The agent mode is divided into static agent and dynamic agent
1.3 static agent
Static proxy needs to define an interface or parent class. The proxy object and the proxy object implement the same interface or inherit the same parent class together. This is its disadvantage and inconvenient to expand. When an interface needs to be added, all implementations should add the same interface
1.4 dynamic agent
Dynamic Proxy can directly generate a Proxy object for a target (proxied object) object (which implements some or some interfaces), and use the newInstance reflection in the Proxy to realize the Proxy mode
1.4.1 Java.lang.reflect.Proxy class can directly generate a proxy object
Proxy.newProxyInstance(ClassLoader loader, Class<?>[] Interfaces, invocationhandler h) generates a proxy object
- Parameter 1: classloader the classloader of the proxy object generally uses the classloader of the proxy object
- Parameter 2: class <? > [] Interfaces the interface to be implemented by the proxy object is generally the interface implemented by the proxy object
- Parameter 3:InvocationHandler h (Interface) execution processing class
1.4.2 invoke() method in invocationhandler
Invoke (object proxy, method, method, object [] args) method: call any method of the proxy class, and this method will be executed
- Parameter 1: proxy object (use with caution)
- Parameter 2: currently executed method
- Parameter 3: the parameter passed from the runtime of the currently executed method
- Return value: the return value of the current method execution
2. Static proxy code
2.1 defining interfaces
package com.jzj.design.demo.proxyDesign.staticproxy; /** * Method interface */ public interface IMethodDAO { void doSomeThing(); }
2.2 implementation of original interface
Interface implementation
package com.jzj.design.demo.proxyDesign.staticproxy; public class LocalMethodImpl implements IMethodDAO { @Override public void doSomeThing() { System.out.println("Original object method call"); } }
2.3 implementation of static proxy object
Implement the same interface, initialize the proxy object through the constructor, and call the method through the object call
package com.jzj.design.demo.proxyDesign.staticproxy; public class StaticProxyMethod implements IMethodDAO { private IMethodDAO teachDAO; /** * Static proxy constructor, initializing interface object * * @param teachDAO */ public StaticProxyMethod(IMethodDAO teachDAO) { this.teachDAO = teachDAO; } @Override public void doSomeThing() { System.out.println("The static agent can add log, authentication and other operations at the beginning---------------------"); teachDAO.doSomeThing(); System.out.println("The static agent ends, the log is output, and the access ends---------------------"); } }
2.4 static proxy results
package com.jzj.design.demo.proxyDesign.staticproxy; public class StaticProxyMain { public static void main(String[] args) { IMethodDAO methodDAO = new LocalMethodImpl(); IMethodDAO staticProxy = new StaticProxyMethod(methodDAO); staticProxy.doSomeThing(); } }
3. Dynamic proxy code
3.1 defining interfaces
package com.jzj.design.demo.proxyDesign.dynamicproxy; /** * The teacher is at the teaching interface */ public interface ITeachDAO { void teach(); }
3.2 method realization
package com.jzj.design.demo.proxyDesign.dynamicproxy; /** * Teachers in Teaching */ public class TeacherServiceImpl implements ITeachDAO { @Override public void teach() { System.out.println("The original object, the teacher is teaching"); } }
3.3 dynamic agent implementation
Construct the object through Proxy newInstance reflection, and then enhance the specific method through InvocationHandler
package com.jzj.design.demo.proxyDesign.dynamicproxy; import java.lang.reflect.Proxy; /** * Dynamic agent */ public class DynamicTeachProxy { /** * Target object */ private Object target; //Constructor initializes the target object public DynamicTeachProxy(Object target) { this.target = target; } //Generates a proxy object for the target object reflection public Object getProxyInstance() { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), (proxy, method, args) -> { System.out.println("--------Dynamic agent- Teacher's preparation before teaching--------"); Object value = method.invoke(target, args); System.out.println("--------Dynamic agent- The teacher finished his work after teaching--------"); return value; }); } }
3.4 dynamic agent results
package com.jzj.design.demo.proxyDesign.dynamicproxy; public class DynamicTestMain { public static void main(String[] args) { ITeachDAO target = new TeacherServiceImpl(); //Create a proxy object for the target object DynamicTeachProxy proxy = new DynamicTeachProxy(target) ; ITeachDAO proxyObject =(ITeachDAO) proxy.getProxyInstance(); proxyObject.teach(); } }