When using a dynamic proxy, it is curious what the newly generated class looks like. Fortunately, through some information to eliminate the doubts in the mind.
There is an AOP (aspect-oriented) mechanism in the spring framework that is used at work, only to know that it regenerates the class again and adds the later defined logic to the slice. This achieves dynamic addition of some functions on the original class. such as log printing, interception of information, etc.
This is only concerned with dynamic proxy technology to generate a new class, regardless of how the virtual machine to generate the class, what bytecode generation technology, how to generate bytecode and other such a series of actions. Now only cares about what the last generation of new classes looks like, What is the difference between it and the old class? In order to get the bytecode of the generated proxy class and decompile the code that we can read, we need to implement a dynamic proxy example.
Example
Interface
Package note.com;/** * Girl interface * @author LXZ * */public interface Igirl { void SayHello ();}
interface implementation, but also a class that needs to take advantage of the dynamic proxy extension feature
Package note.com;/** * Specific Girl * @author LXZ * */public class Mygirl implements Igirl {public void SayHello () { Sy Stem.out.println ("Ruhuasiyu pomegranate elder sister");} }
Proxy Implementation Class
Package Note.com;import Java.lang.reflect.invocationhandler;import Java.lang.reflect.method;import java.lang.reflect.proxy;/** * Proxy class * Function: Introduction to IGIRL Implementation class * @author LXZ * */public class Proxygirl implements Invocationhandler { Object originalobj; Object bind (Object originalobj) { this.originalobj = originalobj; Return Proxy.newproxyinstance (Originalobj.getclass () . getClassLoader (), Originalobj.getclass (). getInterfaces (), this ); } public object invoke (object proxy, Method method, object[] args) throws Throwable { System.out.println ("The first beauty is: "); Return Method.invoke (originalobj, args);} }
Test class
Package note.com;/** * Testing class * * @author LXZ * */public class Test {public static void Main (string[] args) { IG IRL Hello = (igirl) new Proxygirl (). bind (New Mygirl ()); Hello.sayhello ();
System.out.println (Hello.getclass (). GetName ());} }
Results:
The first beauty is:
Ruhuasiyu Pomegranate Sister
Com.sun.proxy. $Proxy 0
This shows that the true type of Hello is $proxy0, what it looks like and looks down.
Proxy class bytecode decompile results
Package Note.com;import Java.lang.reflect.invocationhandler;import Java.lang.reflect.method;import Java.lang.reflect.proxy;import java.lang.reflect.undeclaredthrowableexception;/** * Anti-compilation result of dynamically generated class bytecode * */public final Class $Proxy 0 extends Proxy implements Igirl {private static Method m3; private static Method M1; private static Method M0; private static Method m2; /* The constructor passes in the proxy class that accesses the real object, which is actually the new Proxygirl () in the previous example test ()/protected $Proxy 0 (Invocationhandler h) {Super (H ); }/* Proxy implementation SayHello, */public void SayHello () {try {This.h.invoke (this, M3, null); } catch (RuntimeException localruntimeexception) {throw localruntimeexception; } catch (Throwable localthrowable) {throw new undeclaredthrowableexception (localthrowable); }/* * Proxy implementation inherits from Equals */public void Equals () {try {This.h.invoke (this, M1, n ULL); } catch (Runtimeexception localruntimeexception) {throw localruntimeexception; } catch (Throwable localthrowable) {throw new undeclaredthrowableexception (localthrowable); The hashcode */public int hashcode () {try {return (Integer) This is inherited from object by the proxy implementation. H.invoke (this, M0, null); } catch (RuntimeException localruntimeexception) {throw localruntimeexception; } catch (Throwable localthrowable) {throw new undeclaredthrowableexception (localthrowable); }/* * Proxy implementation inherits from object's ToString */public String tostring () {try {return (String) thi S.h.invoke (this, M2, null); } catch (RuntimeException localruntimeexception) {throw localruntimeexception; } catch (Throwable localthrowable) {throw new undeclaredthrowableexception (localthrowable); }/* * Initialize all methods in real objects */static {try {m3 = CLass.forname ("Note.com.IGirl"). GetMethod ("SayHello", new Class[0]); M1 = Class.forName ("Java.lang.Object"). GetMethod ("equals", new class[] {class.forname ("Java.lang.Objec T ")}); M0 = Class.forName ("Java.lang.Object"). GetMethod ("equals", new class[0]); M2 = Class.forName ("Java.lang.Object"). GetMethod ("equals", new class[0]); } catch (Nosuchmethodexception localnosuchmethodexception) {throw new Nosuchmethoderror (LOCALNOSUCHMETHODEXCEP Tion.getmessage ()); } catch (ClassNotFoundException localclassnotfoundexception) {throw new Noclassdeffounderror ( Localclassnotfoundexception.getmessage ()); } }}
By observing the post-compilation dynamic class, this logic is not complicated, the main function is to initialize all the methods, to execute a method to invoke our own implementation of the proxy class to execute the extension function and the original class method.
Compare the classes that are generated after the original class and the dynamic proxy:
1, $Proxy 0 accesses the real class object through the Invocationhandler implementation class call.
2, dynamic Proxy extension is not included in $proxy0, but rather callback Invocationhandler interface, implement invoke method extension through subclass.
Before and after using dynamic proxies from the invocation relationship:
Left: is the original invocation relationship, and what logic is executed in the original class.
Right: After a dynamic proxy, the proxy class is called by the object that generates the class through the dynamic proxy class, which invokes the extended logic and then invokes the logic of the original class object. The dynamic expansion of the original class is realized.
Through this way of understanding, I understand the dynamic agent more profound, but also dispel the heart of a doubt.
Ps:
When does dynamic agent use? You can refer to this: Dynamic agent technology to implement design mode-proxy mode
Bytecode deserialization in this article is a reference << in-depth understanding of Java Virtual Machine JVM advanced features and best practices >> this book.
Http://www.cnblogs.com/qinggege/p/5288182.html
The difference between a class generated by dynamic agent technology in Java and the original Class (go)