动态代理:cgib、jdk、java javassist
代理:即为访问对象添加一层控制层,使其间接化,控制层可以为对象访问添加操作属性。
一、cglib:Code Generation library
-
基于ASM(java字节码操作码)的高性能代码生成包
-
被许多AOP框架使用
-
区别于JDK动态代理,cglib不需要实现接口。
实例:
import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class MyMethodInterceptor implements MethodInterceptor { public String myFun(String arg){ return "hello," + arg ; } public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { String methodName = method.getName(); System. out .println( "[intercept] fun invoked before" ); String result = (String)args[0] + "..." ; System. out .println( result ); System. out .println( "[intercept] fun invoked after" ); return result; } public Object createProxy(){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(MyMethodInterceptor. class ); enhancer.setCallback( this ); return enhancer.create(); } public static void main(String[] args) { MyMethodInterceptor ss = new MyMethodInterceptor(); MyMethodInterceptor proxy = (MyMethodInterceptor)ss.createProxy(); c1.myFun( "cglib test" ); } }
通用工具类:
package org.windwant.spring.core.proxy; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * Created by windwant on 2016/6/4. */ public class MyCGLIBProxy implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); public Object getProxy(Class clazz){ enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("cglib before action"); Object result = methodProxy.invokeSuper(o, objects); System.out.println("cglib after action"); return result; } }
MyCGLIBProxy p = new MyCGLIBProxy(); Performer pp = (Performer) p.getProxy(XXXX.class); pp.XXXX();
二、JDK动态代理
package org.windwant.spring.core.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Created by windwant on 2016/6/4. */ public class MyJDKProxy implements InvocationHandler{ private Object targetObject; public Object getInstance(Object targetObject){ this.targetObject = targetObject; return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("proxy: before action"); Object resutl = method.invoke(targetObject, args); System.out.println("proxy: after action"); return resutl; } }
MyJDKProxy mp = new MyJDKProxy(); XXX ap = (XXX) mp.getInstance(new APerformer()); ap.XX();
三、Java javassist 动态代理
package org.windwant.spring.core.proxy; import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; /** * Created by windwant on 2016/9/18. */ public class MyJavassistProxy { public Object getProxySelf(String clazz, String pClazz, String methodName, String methodBefore, String methodAfter){ ClassPool cp = ClassPool.getDefault(); CtClass ct; try { ct = cp.get(clazz); if(pClazz != null){ ct.setSuperclass(cp.get(pClazz)); } ct.writeFile(); ct.defrost(); CtMethod m = ct.getDeclaredMethod(methodName); if(methodBefore != null) { m.insertBefore(methodBefore); } if(methodAfter != null) { m.insertAfter(methodAfter); } Class c = ct.toClass(); return c.newInstance(); } catch (Exception e) { e.printStackTrace(); } return null; } }
public void testJavassist(){ String clazz = "org.windwant.spring.core.proxy.Hello"; String methodBefore = "{ System.out.println(\"method before...:\"); }"; String methodAfter = "{ System.out.println(\"method after...:\"); }"; String pClazz = "org.windwant.spring.core.proxy.HelloP"; Hello hello = (Hello) new MyJavassistProxy().getProxySelf(clazz, null, "say", methodBefore, methodAfter); hello.say(); }