Proxy mode
The role of proxy mode is to provide a proxy for other objects to control access to this object. In some cases, a customer does not want or cannot directly reference another object, and the agent object can play a role between the client and the target object.
The role involved in proxy models is:
Abstract role: Declare the common interface of real objects and proxy objects;
Agent Role: The proxy object role contains references to true objects, allowing you to operate real objects, while the agent object provides the same interface as the real object so that you can replace the real object at any time. At the same time, the agent object can add other operations when performing a real object operation, equivalent to the real object.
Real role: The real object represented by the proxy role is the object we finally reference. (See Document 1)
The following examples in "Java and Mode" are:
Abstract role:
Abstract Public Class SUBJECT
{
Abstract public void request ();
}
Real role: Request () method for the Subject () method.
Public Class RealSubject Extends Subject
{
Public realsubject ()
{
}
Public void request ()
{
System.out.println ("from real subject.");
}
}
Agent role:
Public Class ProxySubject Extends Subject
{
Private realsubject realsubject; // uses the real role as the properties of the agent role
Public proxySubject ()
{
}
Public void request () // This method encapsulates the Request method for real objects
{
Prerequest ();
IF (RealSubject == Null)
{
Realsubject = new realsubject ();
}
RealSubject.Request (); // Request method for performing a real object here
PostRequest ();
}
Private void prerequest ()
{
// Something you want to do before requesting
}
Private void postRequest ()
{
// Something you want to do instance
}
}
Client call:
Subject sub = new proxySubject ();
Sub.Request ();
As can be seen from the above code, the customer actually needs to call the request () method of the RealSubject class. Now use proxySubject to proxy RealSubject class, which is also achieved, and other methods are also encapsulated (Prerequest (), postRequest (), can Handle some other questions.
In addition, if you want to use the proxy mode according to the above method, the real role must be in advance, and will use it as the internal properties of the agent object. However, when actual use, a real role must correspond to a proxy role. If a large number of use will result in a sharp expansion of the class; in addition, if you don't know the real role in advance, how do you use a proxy? This issue can be solved by the dynamic proxy class of Java.
2. Dynamic Agent
Java dynamic proxy class is located under the java.lang.reflect package, generally mainly involved two classes:
(1). Interface InvocationHandler: Only one method is defined in this interface (Object Obj, Method Method, Object [] args). When actually use, the first parameter OBJ generally refers to the proxy class, and the method is a method of being proxy, as Request () in the above example, ARGS is the parameter array of the method. This abstract method is dynamically realized in the proxy class. (2) .proxy: This class is a dynamic proxy class, and the role is similar to the proxySubject in the above example, which mainly contains the following:
Protected Proxy (InvocationHandler H): Constructor is estimated to assign a value to the internal H.
Static Class getProxyclass (ClassLoader Loader, Class [] interfaces): Get a proxy class, where Loader is a class loader, Interfaces is an array of all interfaces owned by 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 that can be declared in the Subject interface of the proxy class) ).
The so-called Dynamic Proxy is such a Class: It is a class generated at runtime, when generating it, you must provide a set of Interface to it, then the Class claims that it implements these interface. You can of course use the Class's instance as any of these interfaces. Of course, this Dynamic Proxy is actually a proxy. It doesn't work substantive jobs for you. When you generate it, you have to provide a handler, which takes over the actual work. (See Document 3)
When using dynamic proxy classes, we must implement an InvocationHandler interface, as an example in the first quarter:
Abstract roles (before it is an abstract class, here should be changed to the interface):
Public Interface Subject
{
Abstract public void request ();
}
Specific role RealSubject: 同;
Agent role:
Import java.lang.reflect.method;
Import java.lang.reflect.invocationhandler;
Public class dynamicsubject imports invocationhandler {
Private Object Sub;
Public Dynamicsubject () {
}
Public Dynamicsubject (Object obj) {
Sub = OBJ;
}
Public Object Invoke (Object Proxy, Method Method, Object [] args throws throwable {
System.out.Println ("Before Calling" Method;
Method.invoke (SUB, ARGS);
System.out.println ("After Calling" Method;
Return NULL;
}
}
The internal properties of the agent class are Object classes. When the constructor Dynamicsubject (Object Obj) of this class is actually used; in addition, the invoke method is implemented, Method.Invoke in this method (Sub, Args );
In fact, it is to call the method to be executed by the proxy object. The method parameter SUB is the actual subject object, and Args is the parameter required to perform the corresponding operation of the proxy object. With dynamic proxy classes, we can perform some related operations before or after calling.
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 = new realsubject (); // Specify the proxy class here
InvocationHandler DS = New Dynamicsubject (RS); // Initialization Agent
Class CLS = rs.getClass ();
// The following is a 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 generation
Subject Subject = (Subject) proxy.newproxyinstance (CLS.GetClassLoader (),
CLS.GetInterfaces (), DS);
Subject.Request ();
}
In this way, the object of the agent can be dynamically changed during runtime, and the interface (Subject interface) that needs to be controlled can change and control the way (Dynamicsubject class), which is very flexible. Dynamic agency relationship (see Document 2).
references:
1. 宏, "Java and Mode"
2. Transparent, "Dynamic Agent's Past Today"
3. Forest Hou, "Dynamic Proxy in Java RMI"