10 minutes to help you understand the dynamic agent in Java, what is dynamic proxy? Interested in the small partners can refer to
If the proxy class already exists before the program is run, then this proxy is a static proxy, in which case the proxy class is usually defined in Java code. Typically, proxy classes and delegate classes in static proxies implement the same interface or derive from the same parent class.
I. Overview
1. What is an agent
We all know that the micro-commerce agent, simply said to replace the manufacturers to sell goods, manufacturers "commissioned" agent for its sales of goods. On the micro-business agent, we usually do not know who is behind the manufacturer when we buy from them, that is to say, "The principal" is not visible to us; second, the micro-business agent mainly in the circle of friends as the target customers, which is equivalent to the manufacturers to do a customer group "filter." We have further abstracted the agent and the factory, the former can be abstracted as the proxy class, the latter can be abstracted as the delegate class (the proxy Class). By using proxies, there are usually two advantages and can correspond to the two characteristics of the micro-quotient agents we refer to:
Advantage One: can hide the implementation of the delegate class;
Advantage Two: can realize the decoupling between the client and the delegate class, can do some additional processing without modifying the delegate class code.
2. Static Proxy
If the proxy class already exists before the program is run, then this proxy is a static proxy, in which case the proxy class is usually defined in Java code. Typically, proxy classes and delegate classes in static proxies implement the same interface or derive from the same parent class. Below we use vendor class to represent the manufacturer, Businessagent class represents the micro agent, to introduce the simple implementation of the static agent, the delegate class and the proxy class have implemented the sell interface, the sell interface is defined as follows:
public interface Sell {void Sell (); void ad (); } The Vendor class is defined as follows: public class Vendor implements Sell {public void Sell () { System.out.println ("in Sell Method"); } PU Blic void ad () { system,out.println ("ad method") }
The proxy class businessagent is defined as follows:
public class Vendor implements Sell {public void Sell () { System.out.println ("in Sell Method"), public void AD ( ) { System,out.println ("ad method") }
From the definition of the Businessagent class we can see that static proxies can be implemented by aggregation, allowing the proxy class to hold a reference to a delegate class.
Let's consider this requirement: Add a filter function to the vendor class and sell the goods to college students only. With static proxies, we can do this without modifying the code of the vendor class, simply by adding a judgment to the Sell method in the Businessagent class, as shown here:
public class Businessagent implements Sell { ... public void Sell () { if (iscollegestudent ()) { Vendor.sell (); } } ...
This corresponds to the second advantage of using proxies as we mentioned above: the decoupling between the client and the delegate class can be achieved, and some additional processing is possible without modifying the delegate class code. The limitation of static proxy is that the proxy class must be written before running, and we will focus on the dynamic proxy mode of generating proxy class at runtime.
Second, dynamic agent
1. What is dynamic proxy
Proxy classes are created as dynamic proxies when the program is run. That is, in this case, the proxy class is not defined in Java code, but is dynamically generated at run time according to our "instructions" in Java code. Compared with static proxy, the advantage of dynamic agent is that the function of proxy class can be handled uniformly, without modifying the function of each proxy class. So to speak more abstract, below we combine an example to introduce the dynamic agent of this advantage is how to embody.
Now, let's say we want to implement a requirement: output "before" before executing the method in the delegate class and output "after" when execution is complete. We also use the vendor class in the example above as the delegate class, the Businessagent class as the proxy class to introduce. First we use static proxies to implement this requirement, with the following code:
public class Businessagent implements Sell { private Vendor Mvendor; Public businessagent (Vendor Vendor) { This.mvendor = Vendor; } public void Sell () { System.out.println ("before"); Mvendor.sell (); System.out.println ("after"); } public void ad () { System.out.println ("before"); Mvendor.ad (); System.out.println ("after"); }
From the above code we can understand that through the static proxy implementation of our needs, we need to add the corresponding logic in each method, there are only two methods so the workload is not large, if the sell interface contains hundreds of methods? This time the use of static agents will write many redundant code. By using dynamic proxies, we can make a "unified instruction" that unifies the methods of all proxy classes without having to modify each method individually. Below we will specifically describe how to use dynamic proxy approach to achieve our needs.
2. Using dynamic proxies
(1) Invocationhandler interface
When using dynamic proxies, we need to define a mediation class that is located between the proxy class and the delegate class, which is required to implement the Invocationhandler interface, which is defined as follows:
Public interface Invocationhandler { object Invoke (Object proxy, Method method, object[] args);
From the name of Invocationhandler, we can know that the intermediary class that implements this interface is used as a "call processor". When we invoke the method of the proxy class object, this "call" is forwarded to the Invoke method, the proxy class object is passed in as a proxy parameter, and the parameter method identifies which method of the proxy class we specifically call, and args is the parameter of this method. In this way, our invocation of all methods in the proxy class becomes a call to invoke, so that we can add uniform processing logic to the Invoke method (or different proxy class methods depending on the method parameter). So we simply output "before" in the Invoke method implementation of the mediation class, then invoke the delegate class's Invoke method, and then output "after". Let's take a step-by-step implementation of it.
(2) Definition of the delegate class
Dynamic proxy mode requires that the delegate class must implement an interface, where we implement the Sell interface. The delegate class vendor class is defined as follows:
public class Vendor implements Sell {public void Sell () { System.out.println (' in Sell method '); } public void ad () { system,out.println ("ad method") }
(3) Intermediary class
As we mentioned above, the mediation class must implement the Invocationhandler interface as a call to the processor to "intercept" the proxy class method. The mediation class is defined as follows:
public class Dynamicproxy implements Invocationhandler { private object obj;//obj is the delegate class object; Public dynamicproxy (Object obj) { this.obj = obj; } @Override Public object Invoke (Object proxy, Method method, object[] args) throws Throwable { System.out.println ("before"); Object result = Method.invoke (obj, args); System.out.println ("after"); return result; }
From the above code, we can see that the mediation class holds a delegate class object reference, in the Invoke method called the delegate class object corresponding method (line 11th), see here is not familiar? The delegate class object reference is held by means of aggregation, The external call to invoke is eventually converted to a call to the delegate class object. This is not the static agent we described above a way of implementation? In fact, the mediation class and the delegate class constitute a static proxy relationship, in which the intermediary class is the proxy class, the delegate class is the delegate class; The proxy class and the mediation class also constitute a static proxy relationship, in which the mediation class is the delegate class, and the proxy class is the proxy class. In other words, the dynamic agent relationship consists of two sets of static agent relationships, which is the principle of dynamic proxy. Let's look at how to "instruct" to dynamically generate the proxy class.
(4) Dynamically generated proxy classes
The relevant code for the dynamically generated proxy class is as follows:
public class Main {public static void Main (string[] args) { //Create Mediation class instance dynamicproxy inter = new Dynamicproxy (n EW Vendor ()); Adding this will result in a $proxy0.class file, which is a dynamically generated proxy class file system.getproperties (). Put (" Sun.misc.ProxyGenerator.saveGeneratedFiles "," true "); Gets the proxy class instance Sell Sell Sell = (Sell) (Proxy.newproxyinstance (Sell.class.getClassLoader (), new class[] {Sell.class}, inter)); Invoking the proxy class method through the proxy class object will actually go to the Invoke method call Sell.sell (); Sell.ad (); }
In the above code, we call the proxy class's Newproxyinstance method to get a proxy class instance. This proxy class implements the interface we specify and distributes the method call to the specified calling processor. The declaration of this method is as follows:
Copy CodeThe code is as follows: public static Object newproxyinstance (ClassLoader loader, class<?>[] interfaces, Invocationhandler h) throws IllegalArgumentException
The three parameters of the method have the following meanings:
Loader:Defines the classloder of the proxy class;
Interfaces:List of interfaces implemented by the proxy class
h:Call the processor, which is the class instance we defined above that implements the Invocationhandler interface.
Let's run it and see if our dynamic agents are working properly. The output I run here is:
Explain that our dynamic agent really worked.
Above, we have briefly mentioned the principle of dynamic agent, here is a simple summary: first through the Newproxyinstance method to obtain the proxy class instance, and then we can call the proxy class through this proxy class method, the invocation of the proxy class method will actually call the mediation class (call processor The Invoke method, in the Invoke method we invoke the corresponding method of the delegate class, and can add its own processing logic.
10-minute understanding of dynamic agents in Java