Java Dynamic Proxy, proxy and InvocationHandler, Proxy dynamic proxy
I have read a lot of articles about proxy, understanding and sorting out them.
1. Basic composition of proxy
Abstract role: Declares the common interfaces of the real object and the proxy object, so that the proxy object can be used wherever the real object is used.
Proxy role: The proxy object contains a reference of a real object, so that you can operate on the real object at any time. The proxy object provides the same interface as the real object, so that the real object can be replaced at any time. A proxy Object usually performs an operation before or after the client call is passed to the real object, instead of simply passing the call to the real object. At the same time, the proxy object can perform the real object operation, appending other operations is equivalent to encapsulating real objects.
Real role: It is the target object represented by the proxy object. The real object represented by the proxy role is the object we will reference in the end.
There are three roles: Subject abstract roles, RealSubject real roles, and Proxy roles. Among them, the Subject role defines the interfaces that the RealSubject and Proxy roles should implement. The RealSubject role is used to truly complete the business service functions. The Proxy role is responsible for sending its own request requests, call the request function corresponding to RealSubject to implement business functions.
2. Static proxy
Interface Subject // abstract role {public void doSomething ();} class RealSubject implements Subject // real role {public void doSomething () {System. out. println ("call doSomething ()") ;}} class SubjectProxy implements Subject // proxy role {// The role of the proxy mode is: provides a proxy for other objects to control access to this object. Subject subimpl = new RealSubject (); public void doSomething () {System. out. println ("before"); // subimpl can be performed before the target object is called. doSomething (); System. out. println ("after"); // you can perform related operations after calling the target object} public class Test {public static void main (String [] args) throws Exception {Subject sub = new SubjectProxy (); sub. doSomething ();}}
As you can see, SubjectProxy implements the Subject interface (which is the same as the RealSubject Interface) and supports references of the Subject interface type. In this way, the doSomething method is still called, but the process of instantiating the object has changed. As a result, the proxy class SubjectProxy can automatically add before, after, and other required actions to us.
If you need to implement a new interface in the future, you need to write the implementation method of this interface in the proxy class to make the code of the proxy class bloated. On the other hand, when you need to change the abstract role interface, undoubtedly, real roles and proxy roles also need to be changed.
3. JDK dynamic proxy
Interface Subject {public void doSomething ();} class RealSubject implements Subject {public void doSomething () {System. out. println ("call doSomething ()") ;}} class ProxyHandler implements InvocationHandler {private Object tar; // bind the delegate Object and return the proxy class public Object bind (Object tar) {this.tar = tar; // bind all interfaces implemented by this class to obtain the Proxy class return Proxy. newProxyInstance (tar. getClass (). getClassLoader (), tar. getClass (). getInterfaces (), this);} public Object invoke (Object proxy, Method method, Object [] args) throws Throwable // does not depend on the specific interface implementation {Object result = null; // The proxy type is the Object base class. // the so-called AOP programming can be implemented here. // The result = method is executed before calling a specific function method. invoke (tar, args); // after calling a specific function method, execute the function to process return result;} public class Test {public static void main (String args []) {ProxyHandler proxy = new ProxyHandler (); // bind all interfaces implemented by this class Subject sub = (Subject) proxy. bind (new RealSubject (); sub. doSomething ();}}
During the call process, a common proxy class is used to encapsulate the RealSubject instance, and then the Jdk proxy factory method is called to instantiate a specific proxy class. Finally, call the doSomething method of the proxy, additionally, the before and after methods can be reused at Will (as long as we use this generic proxy class in the calling code to wrap any proxy class we want to wrap ). When the interface changes, although the proxy class needs to be changed, our proxy class does not need to be changed. Although this call is flexible enough, you can dynamically generate a specific proxy class without creating a proxy class that implements a specific interface on your own.