Implementation of dynamic Agent
Mode used: Proxy mode.
The role of proxy mode is to provide a proxy for other objects to control access to this object. Like a rental intermediary.
Two kinds of dynamic agents:
(1)JDK dynamic Agent , JDK Dynamic agent is implemented by the reflection mechanism inside Java, the target class is based on the Unified Interface (Invocationhandler)
(2)cglib dynamic agent, Cglib dynamic agent is the base of the use of ASM to achieve, cglib this third-party class library implementation of dynamic proxy application more extensive, and more efficient advantages.
The main application of the framework:
Interceptors in Aop,struts2 in spring
Specific implementation:
1. Defining interfaces and implementing classes
Interface
1 package com.example.service;2 3 public interface UserService {4 public String getName (int id); 5 6 public Integer Getage (int id); 7}
Implementation class
Package Com.example.service.impl;import Com.example.service.userservice;public class Userserviceimpl implements UserService {public String getName (int id) { System.out.println ("------getName------"); Return "Cat"; } Public Integer getage (int id) { System.out.println ("------getage------"); return ten;} }
2, JDK dynamic agent implementation
Package Com.example.jdk;import Java.lang.reflect.invocationhandler;import Java.lang.reflect.method;import Java.lang.reflect.proxy;public class Myinvocationhandler implements Invocationhandler {private Object target; /** * Binds the delegate object and returns a proxy class * * @param target * @return */Public Object bind (object target) {This . target = target; Get the proxy object return Proxy.newproxyinstance (Target.getclass (). getClassLoader (), Target.getclass (). Getinte Rfaces (), this); To bind the interface (this is a flaw, cglib compensates for this flaw)} @Override public object invoke (object proxy, method, object[] args) throws Throwable {if ("GetName". Equals (Method.getname ())) {System.out.println ("------before" + Method.getnam E () + "------"); Object result = Method.invoke (target, args); SYSTEM.OUT.PRINTLN ("------after" + method.getname () + "------"); return result; } else {Object result = Method.invoke (target, args); return result; } }}
Package Com.example.jdk;import Com.example.service.userservice;import com.example.service.impl.userserviceimpl;/* * * Test class */public class Runjdk {public static void Main (string[] args) { Myinvocationhandler proxy = new Myinvocat Ionhandler (); UserService userserviceproxy = (userservice) proxy.bind (New Userserviceimpl ()); System.out.println (Userserviceproxy.getname (1)); System.out.println (Userserviceproxy.getage (1));} }
Operation Result:
------Before getName------
------getName------
------After getName------
Cat
------getage------
10
3, Cglib dynamic Agent implementation:
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.
Core classes of Cglib:
net.sf.cglib.proxy.enhancer– Major Enhancement classes
net.sf.cglib.proxy.methodinterceptor– the Main method interception class, which is a sub-interface of the callback interface, requires the user to implement
The proxy class of the Java.lang.reflect.Method class of NET.SF.CGLIB.PROXY.METHODPROXY–JDK can easily implement the invocation of the source object method.
The Net.sf.cglib.proxy.MethodInterceptor interface is the most common type of callback (callback), and it is often used by proxy-based AOP to implement a call to intercept (intercept) methods. This interface only defines a method
public object Intercept (Object object, Java.lang.reflect.Method Method,
Object[] args, Methodproxy proxy) throws Throwable;
The first parameter is the proxy pair image, the second and third parameters are the parameters of the intercepted method and method, respectively. The original method may be called by using the general reflection of the Java.lang.reflect.Method object, or by using the Net.sf.cglib.proxy.MethodProxy object. Net.sf.cglib.proxy.MethodProxy is usually preferred because it is faster.
Package Com.example.cglib;import Org.springframework.cglib.proxy.enhancer;import Org.springframework.cglib.proxy.methodinterceptor;import Org.springframework.cglib.proxy.methodproxy;import Java.lang.reflect.method;public class Cglibproxy implements Methodinterceptor {private Object target; /** * Create proxy Object * * @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 proxy object return Enhancer.create (); } @Override public Object Intercept (object O, Method method, object[] objects, Methodproxy methodproxy) throws Throw Able {System.out.println ("++++++before" + methodproxy.getsupername () + "++++++"); System.out.println (Method.getname ()); Object result = Methodproxy.invokesuper (O, objects); System.out.println ("++++++after" + MEthodproxy.getsupername () + "++++++"); return result; }}
Package Com.example.cglib;import Com.example.service.userservice;import com.example.service.impl.userserviceimpl;/** * Test Cglib */public class Runcglib {public static void main (string[] args) {Cglibproxy cglibproxy = new Cglibproxy (); UserService UserService = (userservice) cglibproxy.getinstance (New Userserviceimpl ()); Userservice.getname (1); Userservice.getage (1); }}
Run Result:
++++++before cglib G e t N a m e "> getName getname0+ +++++
GetName
------getName------
++++++after cglib g e t N a m e "> getName getname0++++++
++++++before cglib g e t A g e " > getage getage1++++++
Getage
------getage------
++++++after cglib g e t A g e " > getage getage1++++++
Implementation of dynamic Agent in Java