Java Dynamic Agent Simple application

Source: Internet
Author: User
Tags dateformat object object throwable

Concept

  Proxy mode is one of the basic design patterns, which is an object that the developer inserts to replace the "actual" object in order to provide additional or different operations. These operations typically involve communication with an "actual" object, so the agent usually acts as a middleman.

The Java dynamic agent is more than a proxy idea because it can dynamically create proxies and dynamically handle calls to proxy methods. All calls made on the dynamic agent are redirected to a single call processor (Invocationhandler), and the job of invoking the processor is to reveal the type of invocation and determine the appropriate policy.

The implementation mechanism of the Java dynamic Agent adopts the thought of reflection and has the basic knowledge about reflection, which can be found in the blog Java launch mechanism.

principle

 Spring  one of the core AOP Implementation Techniques is the use of dynamic agent mechanism, authorization authentication, log and transaction management can adopt dynamic agent, using dynamic agent mechanism can reduce code duplication, reduce system coupling degree. The Java Dynamic Agent API is located under the Java.lang.reflect package, and implementing a dynamic proxy involves the following two key steps:

1. Implement the Invocationhandler interface

The Invocationhandler interface defines only one method.

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

Proxy: Agent Object

Method: The object of the class being proxied

args: Array of proxy method parameters

The proxy parameter represents the agent object, in case the developer needs to differentiate between the source of the request, but in many cases the developer does not care. Invocationhandler usually needs to hold a reference to the proxy object, and all calls made on the dynamic proxy are redirected to the invoke method of the Invocationhandler interface. Invoking the method method of the Proxied object inside the Invoke method allows the developer to add the required logic before and after the methods call. If you just want to proxy some methods, the developer can add the appropriate filter in the invoke method, through the method parameter can get a lot of information about the methods themselves.

2. Create a dynamic proxy class instance from proxy

Proxy is the parent class of all dynamic proxy classes and provides a static method Newproxyinstance is responsible for creating instances of dynamic proxy classes.

public static Object newproxyinstance (ClassLoader loader, class<?>[] interfaces, Invocationhandler h) throws I Llegalargumentexception

Loader: Class loader (usually can get its classloader from an object that has already been loaded)

Interfaces: List of interfaces that the proxy class needs to implement (typically the list of interfaces implemented with the proxy class)

H: An implementation of theInvocationhandler interface

The newproxyinstance method dynamically generates a Proxy subclass based on the incoming interface list interfaces in the virtual machine, and implements the incoming interface list interfaces , and then returns an instance of the class. So the returned object can be transformed into any interface passed in, and the invocation of all methods within the interface is redirected to the third parameter H 's invoke method.

The implementation of Java Dynamic Agent Underlying principle is quite complex. All in all, it is the class loader and interface that are passed in according to the newproxyinstance method, generate the binary bytecode of the proxy class, and then use the reflection mechanism to create an instance of the proxy class, and the invocation of the proxy class method inside the proxy class is redirected to the the Invoke method in Invocationhandler, within the invoke method, encapsulates the invocation of the proxy method, plus the developer's own logic.

Application

The following is a demonstration of two simple examples: Method performance monitoring and log management

Entity class

public class User {private string name;public User (String name) {super (); this.name = name;} Public String GetName () {return name;} public void SetName (String name) {this.name = name;}}

Interface

public interface Userdao {void AddUser (user user); void DeleteUser (string name); void UpdateUser (string name);}

Implementation class

public class Userdaoimpl implements Userdao {@Overridepublic void AddUser (user user) {System.out.println ("Add user named" + user.getname () + "..."); try {thread.sleep (1000);} catch (Interruptedexception e) {e.printstacktrace ();}} @Overridepublic void DeleteUser (String name) {System.out.println ("delete user named" + name + "..."); try {thread.sleep (15 00);} catch (Interruptedexception e) {e.printstacktrace ();}} @Overridepublic void UpdateUser (String name) {System.out.println ("update user named" + name + "..."); try {Thread.Sleep (20 00);} catch (Interruptedexception e) {e.printstacktrace ();}}}
Method Performance Monitoring

Monitoring the performance efficiency of the method, where the method run time is simply used as the evaluation criteria. The traditional approach is to record the time before and after each method execution, and then calculate the elapsed time. Using the dynamic agent mechanism, you can unify the above operations into Invocationhandler and create a proxy class to monitor all the methods.

Invocationhandler Implementation Class

Import Java.lang.reflect.invocationhandler;import Java.lang.reflect.method;public class Performanceinterceptor Implements Invocationhandler {Private Object Proxied;public performanceinterceptor (Object proxied) {this.proxied = proxied;} @Overridepublic object Invoke (Object proxy, Method method, object[] args) throws Throwable {Long startTime = System.curren Ttimemillis (); Object obj = Method.invoke (proxied, args); Long endTime = System.currenttimemillis (); System.out.println ("Method" + method.getname () + "Execution Time:" + (endtime-starttime) * 1.0/1000 + "s"); return o BJ;}}

Test class

Import Java.lang.reflect.invocationhandler;import Java.lang.reflect.proxy;import Org.junit.test;public class performanceinterceptortest {@Testpublic void Testinvoke () {Userdao Userdao = new Userdaoimpl (); Class<?> cls = Userdao.getclass (); Invocationhandler handler = new Performanceinterceptor (Userdao); Userdao proxy = (Userdao) proxy.newproxyinstance (Cls.getclassloader (), Cls.getinterfaces (), handler);p Roxy.adduser ( New User ("Tom"));p Roxy.deleteuser ("Tom");p Roxy.updateuser ("Tom");}

Test results

Add user named Tom ... Method addUser execution Time:1.0sdelete user named Tom ... Method deleteuser execution time:1.5supdate user named Tom ... Method UpdateUser Execution time:2.0s
Log Management

Sometimes developers need to print some information at the end of a method's execution and execution, and a dynamic agent can perform simple log management of all methods or methods and write to the specified file.

Invocationhandler Implementation Class

Import Java.io.file;import Java.io.filewriter;import Java.io.ioexception;import Java.lang.reflect.invocationhandler;import Java.lang.reflect.method;import Java.text.dateformat;import Java.text.simpledateformat;public class Loginterceptor implements Invocationhandler {private Object Proxied;public Static final String Path = "Run.log";p ublic loginterceptor (Object proxied) {this.proxied = proxied;} Public String Beforemethod (method) {return getformatedtime () + "Method:" + method.getname () + "Start running\r\n" ;} Public String Aftermethod (method) {return getformatedtime () + "Method:" + method.getname () + "End running\r\n";} @Overridepublic object Invoke (Object proxy, Method method, object[] args) throws Throwable {write (path, Beforemethod (meth OD)); Object object = Method.invoke (proxied, args); write (path, aftermethod); return object;} Public String Getformatedtime () {DateFormat formater = new SimpleDateFormat ("Yyyy-mm-dd hh:mm:ss"); return Formater.format (System.currenttiMemillis ());} public void Write (string path, string content) {FileWriter writer = null;try {writer = new FileWriter (path), True ); Writer.write (content); Writer.flush ();} catch (IOException e) {e.printstacktrace ();} finally {if (null! = writer) {try {writer.close ();} catch (IOException e) {E.P Rintstacktrace ();}}}}

Test class

Import Java.lang.reflect.invocationhandler;import Java.lang.reflect.proxy;import Org.junit.test;public class loginterceptortest {@Testpublic void Testinvoke () {Userdao Userdao = new Userdaoimpl (); Class<?> cls = Userdao.getclass (); Invocationhandler handler = new Loginterceptor (Userdao); Userdao proxy = (Userdao) proxy.newproxyinstance (Cls.getclassloader (), Cls.getinterfaces (), handler);p Roxy.adduser ( New User ("Tom"));p Roxy.deleteuser ("Tom");p Roxy.updateuser ("Tom");}

Test results

Generate the Run.log file under the project root directory, as follows:

2015-10-07 05:41:02 method:adduser start running2015-10-07 05:41:03 method:adduser end running2015-10-07 05:41:03 Method :d eleteuser start running2015-10-07 05:41:05 method:deleteuser end running2015-10-07 05:41:05 Method:updateUser start running2015-10-07 05:41:07 Method:updateuser End Running
Summary

  Despite the excellent design of the Java dynamic Agent mechanism, the drawback is that the Java Dynamic Agent can only proxy classes that implement the interface. If you want to proxy a class that does not implement any interfaces, this is a rare situation, and you need to use cdlib. the Java dynamic Agent mechanism is one of the important techniques to realize AOP programming, and dynamic agent is not a tool that developers use everyday, but in some special scenarios, using dynamic proxy can solve some kinds of problems very well.

Java Dynamic Agent Simple application

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.