AOP原理和事務
- AOP
- AOP底層原理
- 比如下面的代碼案例手動模擬AOP
- 動態代理詳解
- JDK動態代理
- 具體實現
AOP
AOP底層原理
當實現了AOP,Spring會根據當前的bean創建動態代理(運行時生成一個代理類)
面試題:為什么執行方法的時候,會執行切面里的通知方法?
比如下面的代碼案例手動模擬AOP
- 模擬切面類
@Component
public class LogAspect {public void logBefore() {System.out.println("aop前置通知");}public void logAfter(){System.out.println("aop后置通知");}public void logReturn(){System.out.println("aop返回通知");}public void logThrowting(){System.out.println("aop異常通知");}}
- 動態代理類
@Component
public class ProxyUserService extends UserService {@Autowiredprivate LogAspect logAspect;@Overridepublic String add() throws InterruptedException {String result = null;try {//調用切面類-前置通知logAspect.logBefore();//調用目標方法result = super.add();//調用切面類返回通知logAspect.logReturn();} catch (Exception e) {//調用切面類-異常通知logAspect.logThrowting();e.printStackTrace();} finally {//調用切面類-后置通知logAspect.logAfter();}return result;}
}
為什么斷點可以進入切面類中的通知方法中?
從上述代碼中可以看到,在AOP動態代理中,在Spring代理類中,幫我們調用了切面中的前置通知,后置通知、返回通知、異常通知這些通知方法,所以斷點可以進入。
動態代理詳解
- jdk動態代理
- cglib動態代理
JDK動態代理
JDK動態代理是基于接口的
- 核心代碼
第一個參數:類加載器
第二個參數:需要代理的接口
第三個參數:InvocationHandler(調用程序處理器,必須重寫invoke方法)
Proxy.newProxyInstance(TestJdkProxy.class.getClassLoader(),UserService.class.getInterfaces(),new MyHandler(new UserService()));
具體實現
- 接口
public interface IUserService {void add();
}
- 實現類
public class UserService implements IUserService{@Overridepublic void add() {System.out.println("添加用戶");}
}
- 自定義一個InvocationHandler(目的是優化代碼降低耦合,提高代碼維護性)
public class MyHandler implements InvocationHandler {Object target;public MyHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("執行前置通知");//執行目標方法Object returnValue = method.invoke(target, args);System.out.println("執行后置通知");return returnValue;}
}
- 測試
@Component
public class TestJdkProxy{public void test(){IUserService instance = (IUserService) Proxy.newProxyInstance(TestJdkProxy.class.getClassLoader(),UserService.class.getInterfaces(),new MyHandler(new UserService()));instance.add();}
}