Java Dynamic Agent Learning "one of Spring AOP Basics"

Source: Internet
Author: User
Tags getmessage throwable

One of the underlying technologies used by Spring AOP is the dynamic agent technology of Java. The dynamic agent technology of Java is mainly around two classes.

Java.lang.reflect.InvocationHandler
Java.lang.reflect.Proxy

The first step is to explain how the Java Dynamic Agent is implemented from the code level.

Business Logic Interface:

  

/** * Create a Human interface, which has a way to eat */public interface person {public    void Eat ();}

Create a class that implements the business interface:

/** * Human interface implementation, the realization of the method of eating */public class Personimpl implements person {    @Override public    void Eat () {        SYSTEM.OUT.P Rintln ("Eat staple food, eat vegetables, drink soup ...");}    }

At this point, if the normal situation is to call the person this interface, and then directly new its implementation class and then call the Eat method, but if you want to implement a person's proxy, And some work before and after the Eat method need to use proxy and invovationhandler;

The implementation class for the Invocationhandler interface (the implementation of additional logic in the proxy class needs to be done here)

/** * proxy class for additional logic implementation classes */public class Invocationhandlerimpl implements Invocationhandler {person person    ;    Public Invocationhandlerimpl (person person) {        This.person = person;    }    @Override Public    object Invoke (Object proxy, Method method, object[] args) throws Throwable {        if (Method.getname ( ). Equalsignorecase ("Eat")) {            System.out.println ("Wash your hands ...");            Method.invoke (person, args);            SYSTEM.OUT.PRINTLN ("brushing");        }        return person;    }}

  

Next is to use proxy to generate proxy classes, proxy requires a business logic interface, proxy class additional implementation of the logic Invocationhandler implementation class

/** * proxy class generates and tests */public class Proxygenerate {    @Test public    void Proxytest () {person person        = new Personimpl ( );        Invocationhandler Invocationhandler = new Invocationhandlerimpl (person);        Person personproxy = (person) proxy.newproxyinstance (Person.class.getClassLoader (), New Class[]{person.class}, Invocationhandler);        Personproxy.eat ();    }    }

  

The output reads as follows:

The proxy class has successfully completed the proxy.

The function of AOP is to add logic before, after, and exception throws, which is the same as the above procedure, so this technique is used to implement a technique of spring AOP, but this is only for the interface implementation, if you want to add the logic of AOP to a class, This proxy dynamic agent technology temporarily does not apply, Spring AOP is applicable to Cglib, support the dynamic agent of the class, but it is not part of this discussion category.

Know how to use the after is not the proxy this feeling is very magical, want to know how to achieve it, you can learn more about Newproxyinstance This method:

  

To find the above, we can see that this is a method of dynamically generating proxy class byte arrays, so we can learn the structure of dynamically generated proxy classes by this method:

/** * proxy class generated and tested */public class Proxygenerate {    @Test public    void Proxywatch () {        byte[] Classbyte = Proxygenera Tor.generateproxyclass ("Persondynamicproxy", New Class[]{person.class});        try {            FileOutputStream var1 = new FileOutputStream ("Persondynamicproxy" + ". Class");            Var1.write (classbyte);            Var1.close ();        } catch (IOException var2) {            throw new Internalerror ("I/O exception saving generated file:" + var2);}}    

Executing the code above generates a. class file for the dynamic proxy object

You can see the structure of the dynamic proxy class after Jd-gui,idea ():

Source code recreated from a. class file by IntelliJ idea//(powered by Fernflower Decompiler)//import Com.smart.bean Factory. Person;import Java.lang.reflect.invocationhandler;import Java.lang.reflect.method;import Java.lang.reflect.Proxy; Import Java.lang.reflect.undeclaredthrowableexception;public Final class Persondynamicproxy extends Proxy implements    person {private static Method M1;    private static Method m3;    private static Method M0;    private static Method m2;    Public Persondynamicproxy (Invocationhandler var1) throws {super (VAR1); The public final Boolean equals (Object var1) throws {try {return (Boolean) Super.h.invoke (this, M1,        New Object[]{var1}). Booleanvalue (); } catch (RuntimeException |        Error var3) {throw var3;        } catch (Throwable var4) {throw new undeclaredthrowableexception (VAR4); }} public final void Eat () throws {try {Super.h.invoke (this, M3, (Object[]) null); } catch (RuntimeException |        Error var2) {throw var2;        } catch (Throwable var3) {throw new undeclaredthrowableexception (VAR3); }} public final int hashcode () throws {try {return (Integer) Super.h.invoke (This, M0, (object[        ]). Intvalue (); } catch (RuntimeException |        Error var2) {throw var2;        } catch (Throwable var3) {throw new undeclaredthrowableexception (VAR3); }} public final String toString () throws {try {return (String) Super.h.invoke (This, M2, (Object        []) null); } catch (RuntimeException |        Error var2) {throw var2;        } catch (Throwable var3) {throw new undeclaredthrowableexception (VAR3); }} static {try {m1 = Class.forName ("Java.lang.Object"). GetMethod ("equals", New Class[]{class.fo            Rname ("Java.lang.Object")}); M3 = Class.forName ("COM.SMART.BEANFACTORY.PErson "). GetMethod (" Eat ", new Class[0]);            M0 = Class.forName ("Java.lang.Object"). GetMethod ("Hashcode", new Class[0]);        M2 = Class.forName ("Java.lang.Object"). GetMethod ("ToString", new Class[0]);        } catch (Nosuchmethodexception var2) {throw new Nosuchmethoderror (Var2.getmessage ());        } catch (ClassNotFoundException var3) {throw new Noclassdeffounderror (Var3.getmessage ()); }    }}

As you can see, the dynamic proxy class first sets the methods in the source interface to their static properties (method) through the technique of reflection, and then overrides each method.

The overriding logic is implemented using the Invoke method of the Invocationhandler interface, where each invoke method binds the corresponding reflected static property.

For example, if the eat of the person interface above is reflected in a static property that is not M3, overriding the Eat () method is to invoke the method invoke (this, M3, args), where there will be additional logic added in Invoke,

Java Dynamic Agent Learning "one of Spring AOP Basics"

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.