1.
Proxy ModeThe proxy mode provides a proxy for other objects to control access to this object. In some cases, a client does not want or cannot directly reference another object, and the proxy object can play a mediation role between the client and the target object. The proxy mode generally involves the following roles:
Abstract role: Declares the common interfaces of real objects and proxy objects;
Proxy role: The proxy object role contains a reference to a real object to operate on the real object. Meanwhile, the proxy object provides the same interface as the real object to replace the real object at any time. At the same time, the proxy object can append other operations when performing real object operations, which is equivalent to encapsulating real objects.
Real role: The real object represented by the proxy role is the object we will reference in the end. (See document 1) the following uses the example in Java and mode as an example: abstract role: abstract public class Subject {abstract public void request ();} real role: the Subject request () method is implemented. Public class RealSubject extends Subject {public RealSubject () {} public void request () {System. out. println ("From real subject. ") ;}} proxy role: public class ProxySubject extends Subject {private RealSubject realSubject; // public ProxySubject () {} public void request () // This method encapsulates the request Method {preRequest (); if (realSubject = null) {realSubject = new RealSubject ();} realSubject. requ Est (); // The request METHOD postRequest () of the real object is executed here;} private void preRequest () {// something you want to do before requesting} private void postRequest () {// something you want to do after requesting} client call: Subject sub = new ProxySubject (); Sub. request (); from the code above, we can see that the customer actually needs to call the request () method of the RealSubject class, And now uses ProxySubject to proxy the RealSubject class, which achieves the same purpose, other methods (preRequest () and postRequest () are encapsulated to handle other problems. In addition, if you want to use the proxy mode according to the preceding method, the real role must exist beforehand and act as the internal attribute of the proxy object. However, in actual use, a real role must correspond to a proxy role. If a large number of roles are used, the class will expand sharply. In addition, if you do not know the real role, how can you use the proxy? This problem can be solved through the dynamic proxy class of Java.
2.
Dynamic proxyThe Java Dynamic proxy class is located in Java. lang. the reflect package generally involves the following two classes: (1 ). interface InvocationHandler: this Interface defines only one Method Object: invoke (Object obj, method Method, j2eejavalanguage jdk1.4apijavalangobject.html "> Object [] args ). In actual use, the first parameter obj generally refers to the proxy class, and the method is the method to be proxy. In the preceding example, request () and args are the parameter arrays of this method. This abstract method is dynamically implemented in the proxy class.
(2 ). proxy: this class is a dynamic Proxy class. Its function is similar to ProxySubject in the previous example. It mainly includes the following content: Protected Proxy (InvocationHandler h): constructor, which is used to assign values to internal h. Static Class getProxyClass (ClassLoader loader, Class [] interfaces): obtains a proxy Class. loader is the Class loader, and interfaces is the array of all interfaces of the real Class. Static Object newProxyInstance (ClassLoader loader, Class [] interfaces, InvocationHandler h): returns an instance of the proxy Class, the returned proxy class can be used as a proxy class (the method declared in the Subject interface of the proxy class can be used ).
Dynamic Proxy is such a class: it is a class generated at runtime. You must provide a set of interfaces to it when generating it, then the class declares that it implements these interfaces. Of course, you can use the class instance as any of these interfaces. Of course, this Dynamic Proxy is actually a Proxy, and it will not do substantial work for you. When generating its instance, you must provide a handler to take over the actual work. (See Article 3) when using a dynamic proxy class, we must implement the InvocationHandler interface. Take the example in Section 1 as an example:
Abstract role(This is an abstract class, which should be changed to an interface here): public interface Subject {abstract public void request ();}
Specific rolesRealSubject: Same as above;
Proxy role:Import java. lang. reflect. method; import java. lang. reflect. invocationHandler; public class DynamicSubject implements InvocationHandler {private Object sub; public DynamicSubject () {} public DynamicSubject (Object obj) {sub = obj;} public Object invoke (Object proxy, Method method Method, object [] args) throws Throwable {System. out. println ("before calling" + method); method. invoke (sub, args); System. out. p Rintln ("after calling" + method); return null ;}} the internal attribute of this proxy class is the Object class. In actual use, the class's constructor DynamicSubject (Object obj) in addition, the invoke method is implemented in this class. invoke (sub, args) is actually the method to be executed to call the proxy object. The method parameter sub is the actual proxy object, args is the parameter required to perform the corresponding operation on the proxy object. Through the dynamic proxy class, we can execute some related operations before or after the call.
Client: Import java. lang. reflect. invocationHandler; import java. lang. reflect. proxy; import java. lang. reflect. constructor; import java. lang. reflect. method; public class Client {static public void main (String [] args) throws Throwable {RealSubject rs = new RealSubject (); // specify InvocationHandler ds = new DynamicSubject (rs) as the proxy Class; // initialize the proxy Class cls = rs. getClass (); // The following is the decomposition STEP/* Class c = Proxy. getProxyClass (cls. getClassLoader (), cls. getInterfaces (); Constructor ct = c. getConstructor (new Class [] {InvocationHandler. class}); Subject subject = (Subject) ct. newInstance (new Object [] {ds}); * // The following is a one-time Subject subject = (Subject) Proxy. newProxyInstance (cls. getClassLoader (), cls. getInterfaces (), ds );
Subject. request ();} in this way, the proxy object (RealSubject) can be dynamically changed at runtime, and the interface to be controlled (Subject Interface) can be changed at runtime, the control method (DynamicSubject class) can also be dynamically changed to achieve a Flexible Dynamic proxy relationship (see document 2 ). References: 1. macro, Java and Mode
2. Transparency, past and present of Dynamic Proxy 3. Forest Hou, application of Dynamic Proxy in Java RMI