Java Dynamic Agent Learning

Source: Internet
Author: User
Tags throwable

Dynamic proxy Classes

The Java dynamic proxy class is located under the Java.lang.reflect package, which generally involves the following two classes:

  1.Interface Invocationhandler

Only one method is defined in the interface:

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

When actually used, the first parameter, obj, generally refers to the proxy class, which method is the proxy, as in the previous example, request (), args is the parameter array for the method (NULL when no parameter is set).

This abstract method is implemented dynamically in the proxy class.

  2.Proxy

The class is a dynamic proxy class that acts like the proxysubject in the example above, which mainly includes the following:

Protected Proxy (Invocationhandler H): constructor, used to assign values to internal invocation handler.

Static class<?> Getproxyclass (ClassLoader loader, class<?> .... Interfaces): Loader is a class loader, Interfaces is an array of all the interfaces owned by the real class.

Static Object newproxyinstance (ClassLoader loader, class<?>[] interfaces, Invocationhandler h): Returns an instance of the proxy class, The returned proxy class can be used as a proxy class (you can use the method declared by the proxy class in the subject interface).

Dynamic proxy class Description

The so-called dynamic Proxy is a class:

It is the class generated at runtime and you must provide a set of interface to it when it is generated, and then the class declares that it implements these interface.

You can certainly use this class instance as any of these interface.

Of course, this dynamic proxy is actually a proxy, it will not do a substantial job for you, in the generation of its instance you must provide a handler, it takes over the actual work.

When using dynamic proxy classes, we must implement the Invocationhandler interface. Each dynamic proxy class will have a invocation handler associated with it.

The real call is done in the Invoke () method of the invocation handler.

Dynamic Agent Steps

1. Create a class that implements the interface Invocationhandler, which must implement the Invoke () method.

2. Create the class and interface that is being proxied.

3. Create a proxy through the static method of proxy newproxyinstance (ClassLoader loader, class<?>[] interfaces, Invocationhandler h).

4. Invoke the method through the proxy.

Dynamic Proxy Example 1:

First define the abstract role and the real role class:

Public interface subject{public    void request ();
public class Realsubject implements subject{    @Override public    Void request ()    {        System.out.println (" From real subject! ");}    }

Then define a Dynamicsubject class:

Import Java.lang.reflect.invocationhandler;import java.lang.reflect.method;/** * The internal properties of the proxy class are of type object, The actual use of this class through the construction method passed in an object. * This class implements the Invoke () method, in which Method.invoke () is actually the method to invoke the object being proxied, and the method parameter sub indicates that the method belongs to a sub. * With dynamic proxy classes, we can add some additional methods to the real object before and after the method * */public class Dynamicsubject implements invocationhandler{    //references to real objects    private Object Sub;        Public dynamicsubject (Object obj)    {        this.sub = obj;            }        @Override Public    object Invoke (Object proxy, Method method, object[] args)            throws Throwable    {        System.out.println ("before calling:" + method);                Method        Method.invoke (sub, args) is invoked by reflection;                System.out.println ("After calling:" + method);        return null;}    }

When used:

Import Java.lang.reflect.invocationhandler;import Java.lang.reflect.proxy;public class client{public    static void Main (string[] args)    {        Realsubject realsubject = new Realsubject ();        Invocationhandler handler = new Dynamicsubject (realsubject);        class<?> ClassType = Handler.getclass ();        The build agent        //dynamically generates a class (implements the specified interface), generates the class object, translates to interface type        Subject Subject = (Subject) proxy.newproxyinstance (ClassType                . getClassLoader (), Realsubject.getclass (). Getinterfaces (),                handler);        Subject.request ();        When the method is called, it is transferred to the handler takeover by the Invoke () method where the actual completion method executes        System.out.println (Subject.getclass ());//Print out: Class $Proxy 0        //$Proxy 0 is a dynamically generated class during runtime    }}

  In this way, the Proxied object (Realsubject) can be dynamically changed at runtime, the interface that needs to be controlled (subject interface) can be changed at runtime, the control mode (Dynamicsubject Class) can also be changed dynamically, thus realizing a very flexible dynamic agent relationship.

Dynamic Proxy Implementation Example 2:

In this example, an interface is defined:

Public interface foo{public    void DoAction ();}

This interface has two implementation classes:

public class FOOIMPL1 implements foo{    @Override public    void DoAction ()    {        System.out.println (' from Implement 1! ");}    public class FOOIMPL2 implements foo{    @Override public    void DoAction ()    {        System.out.println (' from Implement 2! ");}    

Defines the invocation handler, where the set method makes the actual object replaceable:

Import Java.lang.reflect.invocationhandler;import Java.lang.reflect.method;public class Commoninvocationhandler Implements invocationhandler{    private Object target;    Public Commoninvocationhandler ()    {    } public    Commoninvocationhandler (Object obj)    {        This.target = obj;    }    public void Settarget (Object target)    {        this.target = target;    }    @Override Public    object Invoke (Object proxy, Method method, object[] args)            throws Throwable    {                Return Method.invoke (target, args);}    }

Use:

Import Java.lang.reflect.proxy;public class demo{public    static void Main (string[] args)    {        Commoninvocationhandler handler = new Commoninvocationhandler ();        Foo f = null;        Handler.settarget (New FooImpl1 ());        f = (Foo) proxy.newproxyinstance (Foo.class.getClassLoader (),                new class[] {Foo.class}, handler);                F.doaction ();        System.out.println ("----------------------------");        Handler.settarget (New FooImpl2 ());            F.doaction ();    }}

After running the program output:

From Implement 1!
----------------------------
From Implement 2!

Dynamic Proxy Implementation Example 3:

1, Bookfacade.java

 Public Interface  publicvoid  addbook ();  }  

2, Bookfacadeimpl.java

 Public class Implements Bookfacade {  @Override  publicvoid  Addbook () {          System.out.println ("Add Book Method ... ");      }  }  

3, Bookfacadeproxy.java

  •  PackageNet.battier.proxy; ImportJava.lang.reflect.InvocationHandler; ImportJava.lang.reflect.Method; ImportJava.lang.reflect.Proxy; /*** JDK Dynamic Proxy proxy class * *@authorStudent **/   Public classBookfacadeproxyImplementsInvocationhandler {PrivateObject Target; /*** Bind the delegate object and return a proxy class *@paramTarget *@return      */   Publicobject bind (object target) { This. target =Target; //Get proxy Objectreturnproxy.newproxyinstance (Target.getclass (). getClassLoader (), Target.getclass (). Getinterfaces (), This);//to bind an interface (this is a flaw, cglib compensates for this flaw)} @Override/*** Call Method*/   Publicobject Invoke (Object proxy, Method method, object[] args)throwsthrowable {Object result=NULL; System.out.println ("Things start."); //Execution Methodresult=Method.invoke (target, args); System.out.println ("The end of things."); returnresult; }  }  

    4, Testproxy.java

  •  Packagenet.battier.test; ImportNet.battier.dao.BookFacade; ImportNet.battier.dao.impl.BookFacadeImpl; ImportNet.battier.proxy.BookFacadeProxy;  Public classTestproxy { Public Static voidMain (string[] args) {Bookfacadeproxy proxy=NewBookfacadeproxy (); Bookfacade Bookproxy= (Bookfacade) proxy.bind (NewBookfacadeimpl ());      Bookproxy.addbook (); }  }  

However, the dynamic proxy of the JDK relies on the interface, and if some classes do not implement the interface, then the JDK proxy cannot be used, which will use the Cglib dynamic proxy.

Cglib Dynamic Agent
The dynamic agent mechanism of JDK can only implement the class of the interface, and the class that cannot implement the interface cannot implement the dynamic proxy of the JDK, the cglib is to implement the proxy for the class, his principle is to generate a subclass for the target class, and overwrite the method implementation enhancement, but because inherit is adopted, Therefore, the final decorated class cannot be proxied.
Example
1, Bookfacadecglib.java

    •  Package Net.battier.dao;    Public Interface Bookfacade {  publicvoid  addbook ();  }  

2, Bookcadeimpl1.java

    •  Package Net.battier.dao.impl;   /**   * This is an implementation class that does not implement an interface   *@author  student  *     */ publicclass  BookFacadeImpl1 {  publicvoid  Addbook () {          System.out.println ("An ordinary way to add books ...");}  

3, Bookfacadeproxy.java

  •  PackageNet.battier.proxy; ImportJava.lang.reflect.Method; ImportNet.sf.cglib.proxy.Enhancer; ImportNet.sf.cglib.proxy.MethodInterceptor; ImportNet.sf.cglib.proxy.MethodProxy; /*** Use cglib dynamic agent * *@authorStudent **/   Public classBookfacadecglibImplementsMethodinterceptor {PrivateObject Target; /*** Create proxy Object * *@paramTarget *@return      */   Publicobject GetInstance (object target) { This. target =Target; Enhancer Enhancer=Newenhancer (); Enhancer.setsuperclass ( This. Target.getclass ()); //callback MethodEnhancer.setcallback ( This); //Create a proxy objectreturnenhancer.create (); } @Override//callback Method PublicObject Intercept (Object obj, Method method, object[] args, methodproxy proxy)throwsthrowable {System.out.println ("Things start.");          Proxy.invokesuper (obj, args); System.out.println ("The end of things."); return NULL; }  }  

4, Testcglib.java

 Packagenet.battier.test; ImportNET.BATTIER.DAO.IMPL.BOOKFACADEIMPL1; ImportNet.battier.proxy.BookFacadeCglib;  Public classTestcglib { Public Static voidMain (string[] args) {bookfacadecglib cglib=NewBookfacadecglib (); BOOKFACADEIMPL1 Bookcglib= (BOOKFACADEIMPL1) cglib.getinstance (NewBookFacadeImpl1 ());      Bookcglib.addbook (); }  }  



  

Java Dynamic Agent Learning

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.