Dynamic proxy class Principle (example code see Anatomy of the Java Reflection Mechanism (iii))
A) understand the dynamic Agent sample process above
A) understand the dynamic Agent sample process above
b) Analysis of class source code for Proxy interface implementation
Let's take a look at the source code of the Proxy implementation class ($Proxy 0) and the flow of the entire dynamic agent.
$Proxy 0 generates the following code:
Import Java.lang.reflect.InvocationHandler; Import Java.lang.reflect.Method; Import Java.lang.reflect.Proxy; Import java.lang.reflect.UndeclaredThrowableException; Public final class $Proxy 0 extends Proxy implements Manager {private static Method M1; private static Method M0; private static Method m3; private static Method m2; Static {try {m1 = Class.forName ("Java.lang.Object"). GetMethod ("equals", new class[] {Class. forname ("Java.lang.Object")}); M0 = Class.forName ("Java.lang.Object"). GetMethod ("Hashcode", new Class[0]); M3 = Class.forName ("Com.ml.test.Manager"). GetMethod ("Test", new Class[0]); M2 = Class.forName ("Java.lang.Object"). GetMethod ("ToString", new Class[0]); } catch (Nosuchmethodexception nosuchmethodexception) {throw new Nosuchmethoderror (nosuchmethodexception.getmess Age ()); } catch (ClasSnotfoundexception classnotfoundexception) {throw new Noclassdeffounderror (Classnotfoundexception.getmessage ()); }} public $Proxy 0 (Invocationhandler invocationhandler) {super (Invocationhandler); @Override Public Final Boolean equals (Object obj) {try {return (Boolean) super.h. Invoke (this, M1, new object[] {obj})). Booleanvalue (); } catch (Throwable throwable) {throw new undeclaredthrowableexception (Throwable); }} @Override public final int hashcode () {try {return ((Integer) Super.h.invoke ( This, M0, null)). Intvalue (); } catch (Throwable throwable) {throw new undeclaredthrowableexception (Throwable); }} public final void Test () {try {Super.h.invoke (this, M3, null); Return } catch (Error e) {} catch (Throwable throwable) {THRow new Undeclaredthrowableexception (Throwable); }} @Override Public final String toString () {try {return (String) Super.h.invoke (This, M2, null); } catch (Throwable throwable) {throw new undeclaredthrowableexception (Throwable); } } }
The introduction of the eye is that the Proxy interface implementation Class implements the interface of the business class (i.e. the Usermanager interface in the example), and inherits the base class proxy class;
Then is the constructor, in the construction method to pass the Businesshandler, and then $proxy0 call the constructor of the parent class proxy, for H assignment (here to see Proxy construction method);
The next thing you see is that this class overrides the Equals, Hashcode, tostring method of the proxy class, and implements the method of the Business class interface (that is, the Usermanager test method). Specific overrides and implementations are all used in the Super.h.invoke (i.e., Proxy.h.invoke) method.
After a simple analysis of the Proxy interface implementation class, let's look at the overall view of the dynamic agent is how to achieve:
First the client initializes the Businesshandler class, calling the class's Newproxyinstance (New Usermanagerimpl ()) method to initialize the proxy interface implementation class above;
Next, the proxy interface implementation class passes the Businesshandler through the constructor (that is, the this in the code) and assigns the value to h through the constructor of the proxy;
Then the client will be able to instantiate the Proxy interface implementation Class $PROXY0, we cast it into the business Implementation Interface (Usermanager) type (why to cast, here is very interesting, if not cast will be an error, here is very good explanation, Because the current environment at all will not know that the Proxy interface implementation class $proxy0 both inherit proxy and implement the business interface Usermanager, but cast to usermanager it can be done, because the current environment has usermanager. This is the point of reflection, where you can invoke any class dynamically at run time and use the specifics of this class. );
Then when we call the test method is actually called the test method in $proxy0, this method is implemented by the Proxy.h invoke method (called the Businesshandler.invoke method);
This is followed by the Invoke method (the argument is this, and args).
This invokes the corresponding method of the Usermanagerimpl, which is then returned to the client.
This completes the entire invocation relationship.
Reflection, reflection, Programmer's pleasure
Through the previous article on the dynamic agent in-depth analysis, and now think of it is very interesting, in fact, the most fundamental mechanism is the reflection mechanism, the runtime dynamically instantiate any class, and invoke its specific details . Now look at the dynamic proxy example, in fact, found here the most critical is in the Proxy.newproxyinstance (..) When the method executes, the $PROXY0 memory bytecode is generated , and when we have the memory bytecode, our reflection becomes powerful, and then we have a series of call relationships.
Through the analysis of the reflection mechanism and the anatomy of the dynamic proxy example, it is found that programming is an interesting thing that we are immersed in.
A final summary: Reflection, Reflection, Programmer's happiness!
Experience: Dynamic agent Generation $Proxy 0 This class illustrates the use of "reflection" as a point of knowledge.
Analysis of the reflection mechanism of Java (IV.)-depth analysis dynamic agent theory and summary