spring原始碼-aop動態代理-5.3
阿新 • • 發佈:2018-12-13
一、動態代理,這是一個很強大的東西哦。研發過程中我們會常用很多業務類,但是存在一個問題。如何在不修改原始碼邏輯的情況下,加入自己的相關邏輯。比如異常處理,日誌記錄等!
二、Java動態代理的兩種方式JDK、CGLIB
三、動態代理的例子
1)需要代理的類
public interface AspectExcuteParent { void test(); } public class AspectExcuteChild implements AspectExcuteParent{ public void test() { System.out.println("test"); } }
2)JDK代理(因為JDK的代理是基於介面做的,所以需要實現一個介面)
public static void main(String[] args) { //建立代理 AspectExcuteParent aspectExcuteParent = (AspectExcuteParent) Proxy.newProxyInstance( //classloader Thread.currentThread().getContextClassLoader(),//代理接收的介面 AspectExcuteChild.class.getInterfaces(), //代理類 new TestInvocationHandler(new AspectExcuteChild())); aspectExcuteParent.test(); } static class TestInvocationHandler implements InvocationHandler{ //所以私有化,目的執行 private Object object;public TestInvocationHandler(Object object) { super(); this.object = object; } /** * @param proxy (代理例項) * @param method (方法) * @param args (引數) * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before"); Object result = method.invoke(object, args); System.out.println("after"); return result; } }
3)cglib的實現方式(基於類的方式實現)
public static void main(String[] args) { //CGLIB建立類 Enhancer enhancer = new Enhancer(); //設定目標代理 enhancer.setSuperclass(AspectExcuteChild.class); //設定回掉 enhancer.setCallback(new TestMethodInterceptor(new AspectExcuteChild())); //建立代理 AspectExcuteChild aspectExcuteChild = (AspectExcuteChild) enhancer.create(); aspectExcuteChild.test(); } static class TestMethodInterceptor implements MethodInterceptor { //儲存的原始物件 private Object object; public TestMethodInterceptor(Object object) { super(); this.object = object; } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { //方法攔截處理 System.out.println("before"); Object result = method.invoke(object, objects); System.out.println("after"); return result; } }
四、動態代理的例子就這麼多,aop中對代理進行了封裝,但是基本處理方式就是這樣的。