Java Dynamic Proxy (JDK and Cglib) detailed parsing _java

Source: Internet
Author: User
Tags reflection throwable

Dynamic Proxy for Java

Agent mode
Proxy mode is a common Java design pattern, his characteristic is that the proxy class has the same interface with the delegate class, the proxy class is mainly responsible for preprocessing the message for the delegate class, filtering the message, forwarding the message to the delegate class, and handling the message afterwards. There is usually an association between a proxy class and a delegate class, the object of a proxy class is associated with an object of a delegate class, and the object of the proxy class does not actually implement the service, but rather provides a specific service by invoking the methods associated with the object of the delegate class.
According to the creation period of the agent, the proxy class can be divided into two kinds.

static agents: created by a programmer or by a specific tool, the source code is automatically generated, and then compiled. Before the program runs, the. class file for the proxy class already exists.

Dynamic Agent: when the program is running, it is created dynamically by using the reflection mechanism.

First look at the static proxy:
1, Count.java

Copy Code code as follows:

Package Net.battier.dao;

/**
* Define an Account interface
*
* @author Administrator
*
*/
Public interface Count {
View Account method
public void Querycount ();

Modify Account Method
public void Updatecount ();

}



2, Countimpl.java
Copy Code code as follows:



Package Net.battier.dao.impl;





Import Net.battier.dao.Count;





/**


* Delegate Class (Contains business logic)


*


* @author Administrator


*


*/


public class Countimpl implements Count {





@Override


public void Querycount () {


System.out.println ("View account Method ...");





}





@Override


public void Updatecount () {


System.out.println ("Modify Account Method ...");





}





}





Countproxy.java


Package Net.battier.dao.impl;





Import Net.battier.dao.Count;





/**


* This is a proxy class (Enhanced Countimpl implementation Class)


*


* @author Administrator


*


*/


public class Countproxy implements Count {


Private Countimpl Countimpl;





/**


* Overwrite default builder


*


* @param Countimpl


*/


Public Countproxy (Countimpl Countimpl) {


This.countimpl = Countimpl;


}





@Override


public void Querycount () {


System.out.println (before "transaction processing");


The method that invokes the delegate class;


Countimpl.querycount ();


System.out.println (after "transaction processing");


}





@Override


public void Updatecount () {


System.out.println (before "transaction processing");


The method that invokes the delegate class;


Countimpl.updatecount ();


System.out.println (after "transaction processing");





}





}





3, Testcount.java
Copy Code code as follows:

Package net.battier.test;

Import Net.battier.dao.impl.CountImpl;
Import Net.battier.dao.impl.CountProxy;

/**
* Test the Count class
*
* @author Administrator
*
*/
public class Testcount {
public static void Main (string[] args) {
Countimpl Countimpl = new Countimpl ();
Countproxy countproxy = new Countproxy (COUNTIMPL);
Countproxy.updatecount ();
Countproxy.querycount ();

}
}



The observation code can be found that each proxy class can only serve one interface, so the program development will inevitably generate too many agents, and all agent operations in addition to the method of invocation, all other operations are the same, then it must be repeated code. The best way to solve this problem is to use a proxy class to complete all the agent functions, and then you must do so using dynamic agents.





Let's take a look at the dynamic agent:


The JDK dynamic proxy contains a class and an interface:


Invocationhandler Interface:
Public interface Invocationhandler {


public object Invoke (Object Proxy,method method,object[] args) throws Throwable;


}


parameter Description:
Object proxy: Refers to the objects being represented.


Methods: The method to invoke


object[] args: Parameters required for method invocation

The subclass of the Invocationhandler interface can be imagined as the final action class of an agent, replacing the proxysubject.

Proxy class:
A proxy class is an action class that specifically completes a proxy that enables you to dynamically build an implementation class for one or more interfaces, which provides the following methods of action:
public static Object newproxyinstance (ClassLoader loader, class<?>[] interfaces,
Invocationhandler h)
Throws IllegalArgumentException
parameter Description:
ClassLoader Loader: Class loader
Class<?>[] Interfaces: Get all the interfaces
Invocationhandler h: A subclass instance that gets the Invocationhandler interface

Ps: Class Loader
The Newproxyinstance () method in the proxy class requires an instance of the ClassLoader class, ClassLoader actually corresponds to the ClassLoader, and there are three kinds of loaders in Java.
Booststrap ClassLoader: This loader is written in C + +, general development is not seen;
Extendsion ClassLoader: Used for extending class loading, generally corresponding to the Jre\lib\ext directory of classes;
Appclassloader: (default) load Classpath specified class, is the most commonly used is a loader.

Dynamic Proxy
Compared with static proxy class is dynamic proxy class, the dynamic proxy class bytecode is generated dynamically by the Java reflection mechanism when the program is running, without the programmer writing its source code manually. Dynamic proxy classes Not only simplify programming, but also improve the scalability of software systems, because the Java reflection mechanism can generate any type of dynamic proxy class. The proxy class and the Invocationhandler interface in the Java.lang.reflect package provide the ability to generate dynamic proxy classes.

Dynamic Proxy Example:
1, Bookfacade.java

Copy Code code as follows:

Package Net.battier.dao;

Public interface Bookfacade {
public void Addbook ();
}



2, Bookfacadeimpl.java
Copy Code code as follows:



Package Net.battier.dao.impl;





Import Net.battier.dao.BookFacade;





public class Bookfacadeimpl implements Bookfacade {





@Override


public void Addbook () {


System.out.println ("Add Book Method ...) ");


}





}





Bookfacadeproxy.java





Package net.battier.proxy;





Import Java.lang.reflect.InvocationHandler;


Import Java.lang.reflect.Method;


Import Java.lang.reflect.Proxy;





/**


* JDK Dynamic Proxy proxy class


*


* @author Student


*


*/


public class Bookfacadeproxy implements Invocationhandler {


Private Object target;


/**


* Bind delegate object and return a proxy class


* @param target


* @return


*/


public object bind (Object target) {


This.target = target;


Get proxy Object


Return Proxy.newproxyinstance (Target.getclass (). getClassLoader (),


Target.getclass (). Getinterfaces (), this); To bind the interface (this is a flaw, cglib compensates for this flaw)


}





@Override


/**


* Call method


*/


public object invoke (object proxy, Method method, object[] args)


Throws Throwable {


Object Result=null;


SYSTEM.OUT.PRINTLN ("Things Begin");


Execution method


Result=method.invoke (target, args);


System.out.println ("The End of Things");


return result;


}





}





3, Testproxy.java
Copy Code code as follows:

Package net.battier.test;

Import Net.battier.dao.BookFacade;
Import Net.battier.dao.impl.BookFacadeImpl;
Import Net.battier.proxy.BookFacadeProxy;

public class Testproxy {

public static void Main (string[] args) {
Bookfacadeproxy proxy = new Bookfacadeproxy ();
Bookfacade bookproxy = (bookfacade) proxy.bind (New Bookfacadeimpl ());
Bookproxy.addbook ();
}

}



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

Cglib Dynamic Agent
The dynamic proxy mechanism of JDK can only broker the class that implements the interface, a class that does not implement an interface cannot implement a dynamic proxy for JDK, which is a proxy for a class that generates a subclass of the specified target class and overrides the method implementation enhancements, but because of the inheritance, the cglib is used to implement the Therefore, the final decorated class cannot be represented.

Example
1, Bookfacadecglib.java

Copy Code code as follows:

Package Net.battier.dao;

Public interface Bookfacade {
public void Addbook ();
}



2, Bookcadeimpl1.java
Copy Code code as follows:

Package Net.battier.dao.impl;

/**
* This is the implementation class that does not implement the interface
*
* @author Student
*
*/
public class BookFacadeImpl1 {
public void Addbook () {
System.out.println ("The general method of adding books ...");
}
}



3, Bookfacadeproxy.java


Copy Code code as follows:



Package net.battier.proxy;





Import Java.lang.reflect.Method;





Import Net.sf.cglib.proxy.Enhancer;


Import Net.sf.cglib.proxy.MethodInterceptor;


Import Net.sf.cglib.proxy.MethodProxy;





/**


* Use Cglib dynamic agent


*


* @author Student


*


*/


public class Bookfacadecglib implements Methodinterceptor {


Private Object target;





/**


* Create proxy objects


*


* @param target


* @return


*/


public object getinstance (object target) {


This.target = target;


Enhancer enhancer = new enhancer ();


Enhancer.setsuperclass (This.target.getClass ());


callback method


Enhancer.setcallback (this);


Create a proxy object


return Enhancer.create ();


}





@Override


callback method


public object intercept (object obj, Method method, object[] args,


Methodproxy proxy) throws Throwable {


SYSTEM.OUT.PRINTLN ("Things Begin");


Proxy.invokesuper (obj, args);


System.out.println ("The End of Things");


return null;








}





}





4, Testcglib.java
Copy Code code as follows:

Package net.battier.test;

Import NET.BATTIER.DAO.IMPL.BOOKFACADEIMPL1;
Import Net.battier.proxy.BookFacadeCglib;

public class Testcglib {

public static void Main (string[] args) {
Bookfacadecglib cglib=new bookfacadecglib ();
BOOKFACADEIMPL1 bookcglib= (BOOKFACADEIMPL1) cglib.getinstance (New BookFacadeImpl1 ());
Bookcglib.addbook ();
}
}

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.