解決SpringAop內部調用時不經過代理類的問題
SpringAop
AOP代理織入時期
- 編譯時織入 – aspectj框架
- 類加載時織入 – aspectj框架
- 運行時織入 – spring-aop
動態代理方式
- JDK – 被代理對象必須需要實現接口
- CGLIB – 采用繼承被代理對象方式實現代理功能
解決SpringAop內部調用時不經過代理類(而是通過this)
方案一
通過編譯時織入或者類加載時織入代碼
方案二
通過當前代理類調用目標方法
getOne()方法中直接調用getAll()時是通過this對象,這時候getAll()方法上的@AopLog就不會被AOP掃描到
@Service @Slf4j public class ServiceImpl implements IService { @Override @AopLog("value=getOne") public void getOne() { log.info("getOne running"); // 直接調用getAll()方法 = this.getAll() getAll(); } @Override @AopLog("value=getAll") public void getAll() { log.info("getAll running"); } }
修改getOne()方法,通過AopContext.currentProxy()方法獲取當前代理類,通過代理類來調用getAll()方法,這時候就是通過代理類調用的
@Service @Slf4j public class ServiceImpl implements IService { @Override @AopLog("value=getOne") public void getOne() { log.info("getOne running"); // 獲取當前代理類,通過代理類來調用getAll()方法 ((IService) AopContext.currentProxy()).getAll(); } @Override @AopLog("value=getAll") public void getAll() { log.info("getAll running"); } @AopLog("value=getById") private void getById() { log.info("getById running"); } }
this使得SpringAop失效之謎
問題描述
類Demo被AOP掃描到,其中有A和B兩個方法,A方法中調用瞭B方法,執行A方法時,B方法的代理沒有生效
問題剖析
我們知道AOP底層使用JDK動態代理和cglib動態代理想結合,通過判斷去創建對應的代理對象。
而不管是那種方法,最終執行完代理後,都會執行目標方法:method.invoke(target,agrs)–>傳入目標對象
所以執行A方法的代理後,執行A的目標方法,此時執行的對象是目標對象,所以目標對象執行A方法是A中隱藏的this
指的就是目標對象,即執行B方法的不再是代理對象而是目標對象,故B方法不會被代理
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- 解決Spring AOP 同類調用失效問題
- SpringBoot中創建的AOP不生效的原因及解決
- Spring AOP 對象內部方法間的嵌套調用方式
- 解決spring AOP中自身方法調用無法應用代理的問題
- 帶你深入瞭解java-代理機制