Java Dynamic agent and Cglib dynamic agent

Source: Internet
Author: User
Tags throwable

First, what is the dynamic agent?

recommended to see dynamic agent before the first look at the reflection click here

  First look at a small case, assuming there is a coffee class a,b,c. There is additive class a,b,c,. The coffee class is now enhanced. (like adding sugar to the brown, milk, etc.).

There are three ways to enhance a class:

1. Inheritance, you can directly inherit the properties and methods of the parent class, adding your own properties and methods. So we have to enhance each kind of coffee, a total need to write 3*3 inheritance class to complete. The enhanced objects and content are immutable.

2. Decorator mode, combine a property that needs to be enhanced in a class that needs to be enhanced. Then we need to write three combinations of coffee classes, each of which adds an add-on interface attribute, and different implementations of the add-on interface can be used to enhance the coffee class. The enhanced content is mutable, but the enhanced object is immutable.

3. Dynamic agents, through an agent factory, to the need to enhance the coffee class and add class, which automatically generated an enhanced proxy class. We just need to implement the Proxy factory class.

Second, the implementation of dynamic Java Agent

  There is a class proxy in Java, which has a static method object proxy = Proxy.newproxyinstance (ClassLoader ClassLoader, class[] interfaces, Invocationhandler); A proxy object can be obtained by this method. Let's take a look at these three parameters.

  The ClassLoader class loader, which is responsible for loading the agent's ClassLoader. For more information about class loader click here

  Class[] The interface that the target class implements is represented by an array of class objects.

The Invocationhandler processor, when invoking the proxy class, is actually called the Invoke () method of the processor. The following is an explanation of the Invoke method.

Object Invoke (Object proxy, Method method, object[] args);

Proxy: Agent object. Method: The way to execute the proxy object. Args: Arguments passed in when invoking a method of a proxy object.

The following paste code implementation

Target class Interface

 Package cn.edu;  Public Interface Waiter {    publicvoid  server ();}

Front-facing notification interface

 Package cn.edu;  Public Interface Advicebefore {    publicvoid  before ();}

Post Notification interface

 Package cn.edu;  Public Interface Adviceafter {    publicvoid after ();}

Agent Factory

 Packagecn.edu;ImportJava.lang.reflect.InvocationHandler;ImportJava.lang.reflect.Method;ImportJava.lang.reflect.Proxy;/*** Agent factory for production of proxy objects * *@authorWanghang **/ Public classProxyfactory {PrivateObject Target;//target Object    PrivateAdvicebefore Advicebefore;//front-facing notifications    PrivateAdviceafter Adviceafter;//Post Notification//build Proxy Object Core method     PublicObject getproxyinstance () {ClassLoader loader= Proxyfactory.class. getClassLoader ();//class LoaderClass[] interfaces = Target.getclass (). Getinterfaces ();//interfaces implemented by the classInvocationhandler H=NewInvocationhandler () {//Processor             PublicObject Invoke (Object proxy, Method method, object[] args)throwsThrowable {if(Advicebefore! =NULL) {advicebefore.before (); //call a pre-notification} Object result= Method.invoke (target, args);//calling the target method                if(Adviceafter! =NULL) {//call the Post notificationAdviceafter.after (); }                returnresult;        }        }; Object Proxy= proxy.newproxyinstance (loader, interfaces, h);//generates a dynamic proxy object with a given three parameters        returnProxy//returns the proxy object    }     PublicAdvicebefore Getadvicebefore () {returnAdvicebefore; }     Public voidSetadvicebefore (Advicebefore advicebefore) { This. Advicebefore =Advicebefore; }     PublicAdviceafter Getadviceafter () {returnAdviceafter; }     Public voidSetadviceafter (Adviceafter adviceafter) { This. Adviceafter =Adviceafter; }     PublicObject Gettarget () {returnTarget; }     Public voidsettarget (Object target) { This. target =Target; }}

Anonymous inner class for testing, implementation of interfaces

 Packagecn.edu;Importorg.junit.Test; Public classproxytest {@Test Public voidFun () {Waiter Waiter=NewWaiter () {//Build target Object@Override Public voidServer () {System.out.println ("In the service ... ");                }        }; Advicebefore before=NewAdvicebefore () {//generate a pre-notification@Override Public voidbefore () {System.out.println ("Welcome to visit!" ");                }        }; Adviceafter After=NewAdviceafter () {@Override Public voidAfter () {System.out.println ("Thank you for coming!");//generate a post-notification            }        }; Proxyfactory proxyfactory=NewProxyfactory ();//Build FactoryProxyfactory.settarget (Waiter); //set the target objectProxyfactory.setadvicebefore (before);//set up a pre-notificationProxyfactory.setadviceafter (after);//set up post notificationsWaiter Proxy= (waiter) proxyfactory.getproxyinstance ();//Get proxy ObjectProxy.server (); //methods to invoke the target object    }    }

Operation Result:

Third, the implementation of Cglib dynamic agent

the implementation of the Java Dynamic Agent requires the target class to implement the interface, and the dynamic proxy cannot be completed without an interface. Cglib Code Genaration Liarbry is a powerful code generation class library that can extend Java classes while the program is running. It does not require the target class to implement the interface, it takes an inherited approach to extend the target class.

The following with Cglib implementation agent, the rest of the class does not change, just change the agent factory, and to waiter add an implementation class Waiterimpl,cglib Proxy is required class, with anonymous class will be error . The parts of the change are as follows.

Waiter Implementation Class

 Package Cn.edu.cglibProxy;  Public class Implements Waiter {    @Override    publicvoid  server () {        //  TODO auto-generated Method Stub        System.out.println ("in service ... ");    }}

Agent Factory class

 PackageCn.edu.cglibProxy;ImportJava.lang.reflect.Method;ImportOrg.springframework.cglib.proxy.Enhancer;ImportOrg.springframework.cglib.proxy.MethodInterceptor;ImportOrg.springframework.cglib.proxy.MethodProxy;/*** Agent factory for production of proxy objects * *@authorWanghang **/ Public classProxyfactory {PrivateObject Target;//target Object    PrivateAdvicebefore Advicebefore;//front-facing notifications    PrivateAdviceafter Adviceafter;//Post Notification//build Proxy Object Core method     PublicObject getproxyinstance () {Enhancer enhancer=Newenhancer ();                Enhancer.setsuperclass (Target.getclass ()); Enhancer.setcallback (NewMethodinterceptor () {@Override PublicObject Intercept (Object proxy, method, object[] args, Methodproxy methodproxy)throwsthrowable {advicebefore.before (); Object result=Method.invoke (target, args);                Adviceafter.after (); returnresult;        }        }); Object Proxy=enhancer.create (); returnProxy//returns the proxy object    }     PublicAdvicebefore Getadvicebefore () {returnAdvicebefore; }     Public voidSetadvicebefore (Advicebefore advicebefore) { This. Advicebefore =Advicebefore; }     PublicAdviceafter Getadviceafter () {returnAdviceafter; }     Public voidSetadviceafter (Adviceafter adviceafter) { This. Adviceafter =Adviceafter; }     PublicObject Gettarget () {returnTarget; }     Public voidsettarget (Object target) { This. target =Target; }}

Test class

 PackageCn.edu.cglibProxy;Importorg.junit.Test; Public classproxytest {@Test Public voidFun () {Waiter Waiter=NewWaiterimpl (); Advicebefore before=NewAdvicebefore () {//generate a pre-notification@Override Public voidbefore () {System.out.println ("Welcome to visit!" ");                }        }; Adviceafter After=NewAdviceafter () {@Override Public voidAfter () {System.out.println ("Thank you for coming!");//generate a post-notification            }        }; Proxyfactory proxyfactory=NewProxyfactory ();//Build FactoryProxyfactory.settarget (Waiter); //set the target objectProxyfactory.setadvicebefore (before);//set up a pre-notificationProxyfactory.setadviceafter (after);//set up post notificationsWaiter Proxy= (waiter) proxyfactory.getproxyinstance ();//Get proxy ObjectProxy.server (); //methods to invoke the target object    }    }

Test results

Iv. Summary 

  Through the above two examples, you can realize the advantages of dynamic agents. Static proxy is written by the programmer manually Good source code, the program is running when the class file already exists, and dynamic agent is at run time as needed to dynamically generate, not only reduce the workload, use more flexible.

Java Dynamic agent and Cglib 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.