三種實現動態代理方式(jdk、cglib、javaassist)
阿新 • • 發佈:2018-12-25
在編寫程式與實現某些功能時,我們經常會使用到動態代理。動態代理是個很簡單但是很有效的東西。在我們平時使用的框架中,像servlet的filter、包括spring提供的aop以及struts2的攔截器都使用了動態代理功能。我們日常看到的mybatis分頁外掛,以及日誌攔截、事務攔截、許可權攔截這些幾乎全部由動態代理的身影。它的實現原理是非常簡單的,就是在方法實現前後加入對應的公共功能,下面我寫了以下三種方式的實現
package com.jfinal.template; import javassist.util.proxy.MethodHandler; import javassist.util.proxy.ProxyFactory; importnet.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import org.junit.Test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Created by TT on 2018-02-05. */ public class CglibTest { @Testpublic void test() throws Exception { //jdk //缺點 必須有介面 //優點 簡單 T1 t1 = (T1)Proxy.newProxyInstance(T1_00.class.getClassLoader(), T1_00.class.getInterfaces(), new T1_01(new T1_00())); t1.say(); //cglib Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(T2.class); enhancer.setCallback(newT2_01(new T2())); T2 t2 = (T2)enhancer.create(); t2.say(); //javaassist ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.setSuperclass(T3.class); proxyFactory.setHandler(new T3_01(new T3())); T3 t3 = (T3)proxyFactory.createClass().newInstance(); t3.say(); } } class T3 { public void say() { System.out.println("ccc"); } } class T3_01 implements MethodHandler { private T3 t3; public T3_01(T3 t3) { this.t3 = t3; } @Override public Object invoke(Object o, Method method, Method method1, Object[] objects) throws Throwable { System.out.println("ccc before"); method.invoke(new T3(), objects); System.out.println("ccc after"); return o; } } class T2 { public void say() { System.out.println("bbb"); } } class T2_01 implements MethodInterceptor { private T2 t2; public T2_01(T2 t2) { this.t2 = t2; } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("before day"); method.invoke(t2, objects); System.out.println("before after"); return o; } } interface T1 { void say(); } class T1_00 implements T1{ @Override public void say() { System.out.println("aaa"); } } class T1_01 implements InvocationHandler { private T1_00 t1_00 = null; public T1_01(T1_00 t1_00) { this.t1_00 = t1_00; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before"); method.invoke(t1_00, args); System.out.println("after"); return proxy; } }