On the implementation of Spring's AOP-dynamic agent

Source: Internet
Author: User
Tags throwable

Speaking of Spring AOP (aspect-oriented programming) is very familiar to the aspect programming (spring is not the focus of this blog post), but let me ask a few questions to see if the students understand that if you know, you can not continue to read:

1. What are the implementation methods of Spring AOP?

2. Why use dynamic agents?

3. How are they implemented?

4. What is the difference between them?

In the following, spring uses dynamic proxy to implement AOP, specifically using the JDK Dynamic agent and Cglib dynamic agent. The purpose of using dynamic proxies is to add functionality based on existing classes. Simply there will be a proxy class that implements the method of the original class and adds new functionality on top of the original class. So there are a number of features that can be implemented:

1. Log processing before and after the method.

2. Perform additional checks, such as validation of parameters.

3. Implement some lazy loading, that is, when instantiating, if you do not call the real method, the properties of this class will not exist (hibernate has such a similar function).

Let's use the simple code to implement how it is proxied, the first is to use the JDK dynamic Proxy implementation:

Define an interface:

 Package Com.hqs.proxy; /**  @author*/Publicinterface  opsystem    {  publicvoid work ();

Define an implementation class:

 Package Com.hqs.proxy; /**  @author*/Publicclassimplements  Opsystem {      Public void Work () {        System.out.println ("Mac is running");}        }

The key position comes, we implement the Invocationhandler of the package of the reflection mechanism of the JDK to carry on the reflection processing, realizes it to implement the Invoke method inside, this invoke method inside the parameter is: the proxy class instance, is used to call method's The method parameter is the actual execution, and the parameter array that args transmits.

 PackageCom.hqs.proxy;ImportJava.lang.reflect.InvocationHandler;ImportJava.lang.reflect.Method;ImportJava.lang.reflect.Proxy; Public classOphandlerImplementsInvocationhandler {Private FinalOpsystem ops;  PublicOphandler (Opsystem Ops) { This. Ops =ops; }         PublicObject Invoke (Object proxy, Method method, object[] args)throwsthrowable {System.out.println ("Before system running");        Method.invoke (OPS, args); System.out.println ("After system running"); return NULL; }         Public Static voidMain (string[] args) {mac Mac=NewMac (); Ophandler Oph=NewOphandler (MAC); Opsystem OS=(Opsystem) proxy.newproxyinstance (Oph.getclass (). getClassLoader (), Mac.getclass (). Getinterfaces (), Oph)                ;        Os.work ();    System.out.println (Os.getclass ()); }} output: Before system Runningmac is Runningafter system runningclassCom.sun.proxy. $Proxy 0

And then see inside the main method, the proxy class instantiation of the object method Proxy.newproxyinstance, this is the JDK reflection method to instantiate the proxy class, of which there are three are, to instantiate the class of proxy classes Loader An array of all interfaces of the class being proxied; the hander processing class, which is used to intercept the classes used. Finally I output a bit of Os.getclass (), you can see is the proxy class instance, not the actual proxy class instance, the advantage of doing so is very convenient to reuse this proxy class, for example, you can call it repeatedly without having to re-instantiate the new class, and the point is that you can intercept different methods , for example, you can Method.getname () to determine what the calling method name is and thus the finer-grained interception method. Let's continue to look at the implementation of Cglib:

 PackageCom.hqs.proxy;ImportJava.lang.reflect.Method;ImportNet.sf.cglib.proxy.Enhancer;ImportNet.sf.cglib.proxy.MethodInterceptor;ImportNet.sf.cglib.proxy.MethodProxy;/*** CGLib Interceptor for method interception *@authorHQs **/ Public classCglibinterceptorImplementsMethodinterceptor {Private FinalMac Mac;  PublicCglibinterceptor (Mac Mac) { This. Mac =mac; } @Override PublicObject Intercept (Object obj, Method method, object[] args, methodproxy methodproxy)throwsthrowable {System.out.println ("Before system running");        Method.invoke (Mac, args); System.out.println ("After system running"); return NULL; }         Public Static voidMain (string[] args) {mac Mac=NewMac ();//instance rather than interfaceMethodinterceptor handler =NewCglibinterceptor (MAC); Mac m=(MAC) enhancer.create (Mac.getclass (), handler);        M.work ();            System.out.println (M.getclass ()); }} output: Before system Runningmac is Runningafter system runningclasscom.hqs.proxy.mac$ $EnhancerByCGLIB $$1f2c9d4a

The first step is to introduce the Cglib package before using his methodinterptor, which also uses Method.invoke to implement the invocation of the proxy class. Its proxy class creates a create method with the enhancer, which passes in the class that needs to be created, as well as the callback object, because Methodinterceptor inherits the callback object. Used to refer to a class before and after a method call.

 Public Interface Methodinterceptor extends Callback

This is the basic implementation of these two classes, so what is the difference between them?

    1. The dynamic proxy of the JDK can only be used for the interface and its implementation class, if there is no implementation class only the interface can also be proxy, here is not an example. Why is the dynamic agent of the JDK only for the interface agent, because this is the JDK definition.
    2. If you do not implement dynamic proxy for the interface that will use the cglib, that is, can be specific to the class agent, you can refer to my code.

These are the fundamental differences, but spring recommends using a dynamic agent for the JDK to program the interface. When using Cglib to do dynamic proxy, it should be noted that its production agent class is stored in the JVM perm space inside, then is not the generated proxy object is not recycled? Actually not, not often recycled but still recycled, when the class is loaded, the ClassLoader of the load class becomes available when the garbage collection is ready to be recycled. That is, after you create all the classes to remove ClassLoader, then this classloader will be recycled, generally very proficient cglib words can be done in-depth development of this piece of content, because it can make amzing things if you are familiar with the words.

If there's a wrong place, welcome to the brick.

  

  

On the implementation of Spring's AOP-dynamic agent

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.