Home >Java >javaTutorial >Detailed explanation of java proxy mode and dynamic proxy mode
1. Agency model
The so-called agency is a person or an organization taking action on behalf of another person or another organization. In some cases, a client does not want or cannot reference an object directly, and a proxy object can act as an intermediary between the client and the target object.
The proxy mode provides a proxy object for an object, and the proxy object controls the reference to the original object.
Example from real life: I am very busy working overtime during the Chinese New Year and have no time to buy train tickets. At this time, I can call the nearby ticketing center and ask them to buy a train ticket for me to go home. Of course, this will Additional labor charges apply. But it should be clear that the ticket center itself does not sell tickets. Only the train station actually sells tickets. The tickets the ticket center sells to you are actually realized through the train station. This is an important point!
In the above example, you are the "customer", the ticket center is the "agent role", the train station is the "real role", and selling tickets is called the "abstract role"!
Agent mode JAVA code example:
Abstract role: abstract class or interface
interface Business { void doAction(); }
Real role: truly implements the business logic interface
Agent role: I did not implement the business logic interface, but called the real role to implement
class BusinessImplProxy implements Business { private BusinessImpl bi; public void doAction() { if (bi==null) { bi = new BusinessImpl(); } doBefore(); bi.doAction(); doAfter(); } public void doBefore() { System.out.println("前置处理!"); } public void doAfter() { System.out.println("后置处理!"); } } //测试类 class Test { public static void main(String[] args) { //引用变量定义为抽象角色类型 Business bi = new BusinessImplProxy(); bi.doAction(); } }
<span></span>
Therefore, with the support of JVM, the proxy class ("agent role") can be dynamically generated at runtime, and we can solve the above problem To solve the problem of code bloat in the proxy mode, after using dynamic proxy, the "agent role" will not be generated manually, but will be dynamically generated by the JVM at runtime by specifying three parameters: class loader, interface array, and call handler.
Dynamic proxy mode JAVA code example:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.lang.reflect.Method; //抽象角色:java动态代理的实现目前只支持接口,不支持抽象类 interface BusinessFoo { void foo(); } interface BusinessBar { String bar(String message); } //真实角色:真正实现业务逻辑方法 class BusinessFooImpl implements BusinessFoo { public void foo() { System.out.println("BusinessFooImpl.foo()"); } } class BusinessBarImpl implements BusinessBar { public String bar(String message) { System.out.println("BusinessBarImpl.bar()"); return message; } } //动态角色:动态生成代理类 class BusinessImplProxy implements InvocationHandler { private Object obj; BusinessImplProxy() { } BusinessImplProxy(Object obj) { this.obj = obj; } public Object invoke(Object proxy,Method method,Object[] args) throws Throwable { Object result = null; doBefore(); result = method.invoke(obj,args); doAfter(); return result; } public void doBefore(){ System.out.println("do something before Business Logic"); } public void doAfter(){ System.out.println("do something after Business Logic"); } public static Object factory(Object obj) { Class cls = obj.getClass(); return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),new BusinessImplProxy(obj)); } } //测试类 public class DynamicProxy { public static void main(String[] args) throws Throwable { BusinessFooImpl bfoo = new BusinessFooImpl(); BusinessFoo bf = (BusinessFoo)BusinessImplProxy.factory(bfoo); bf.foo(); System.out.println(); BusinessBarImpl bbar = new BusinessBarImpl(); BusinessBar bb = (BusinessBar)BusinessImplProxy.factory(bbar); String message = bb.bar("Hello,World"); System.out.println(message); } }
Program flow description:
new BusinessFooImpl(); Create a "real role" and pass it to the factory method BusinessImplProxy.factory(), and then Initialize the "invocation handler" - the class that implements InvocationHandler. And returns a dynamically created proxy class instance. Since the "agent role" must also implement the business logic methods provided by the "abstract role", it can be transformed down to BusinessBar and assigned to the reference bb pointing to the BusinessBar type.
newProxyInstance(ClassLoader loader, Class6b3d0130bba23ae47fe2b8e8cddf0195[] interfaces, InvocationHandler h) method allows programmers to specify parameters and dynamically return the required proxy class, while the invoke(Object proxy, Method method, Object[] args) method It is dynamically called by the JVM at runtime. When executing the "bb.bar("Hello,World");" method, the JVM dynamically assigns an "invocation handler", passes parameters to the outer invoke, and calls method.invoke(obj, args) to actually execute it!
BusinessImplProxy.Factory static method is used to dynamically generate proxy classes ("agent roles"). According to different business logic interfaces BusinessFoo and BusinessBar, proxy roles are dynamically generated at runtime. "Abstract role", "agent role" and invocation handler (class that implements the InvocationHandler interface) can all be changed, so JAVA's dynamic proxy is very powerful.
For more detailed explanations of Java proxy mode and dynamic proxy mode, please pay attention to the PHP Chinese website!