解決SpringAop內(nèi)部調(diào)用時不經(jīng)過代理類的問題
SpringAop
AOP代理織入時期
- 編譯時織入 - aspectj框架
- 類加載時織入 - aspectj框架
- 運(yùn)行時織入 - spring-aop
動態(tài)代理方式
- JDK - 被代理對象必須需要實現(xiàn)接口
- CGLIB - 采用繼承被代理對象方式實現(xiàn)代理功能
解決SpringAop內(nèi)部調(diào)用時不經(jīng)過代理類(而是通過this)
方案一
通過編譯時織入或者類加載時織入代碼
方案二
通過當(dāng)前代理類調(diào)用目標(biāo)方法
getOne()方法中直接調(diào)用getAll()時是通過this對象,這時候getAll()方法上的@AopLog就不會被AOP掃描到
@Service
@Slf4j
public class ServiceImpl implements IService {
? ? @Override
? ? @AopLog("value=getOne")
? ? public void getOne() {
? ? ? ? log.info("getOne running");
? ? ? ? // 直接調(diào)用getAll()方法 = this.getAll()
? ? ? ? getAll();
? ? }
? ? @Override
? ? @AopLog("value=getAll")
? ? public void getAll() {
? ? ? ? log.info("getAll running");
? ? }
}修改getOne()方法,通過AopContext.currentProxy()方法獲取當(dāng)前代理類,通過代理類來調(diào)用getAll()方法,這時候就是通過代理類調(diào)用的
@Service
@Slf4j
public class ServiceImpl implements IService {
? ? @Override
? ? @AopLog("value=getOne")
? ? public void getOne() {
? ? ? ? log.info("getOne running");
? ? ? ? // 獲取當(dāng)前代理類,通過代理類來調(diào)用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方法中調(diào)用了B方法,執(zhí)行A方法時,B方法的代理沒有生效
問題剖析
我們知道AOP底層使用JDK動態(tài)代理和cglib動態(tài)代理想結(jié)合,通過判斷去創(chuàng)建對應(yīng)的代理對象。
而不管是那種方法,最終執(zhí)行完代理后,都會執(zhí)行目標(biāo)方法:method.invoke(target,agrs)-->傳入目標(biāo)對象
所以執(zhí)行A方法的代理后,執(zhí)行A的目標(biāo)方法,此時執(zhí)行的對象是目標(biāo)對象,所以目標(biāo)對象執(zhí)行A方法是A中隱藏的this
指的就是目標(biāo)對象,即執(zhí)行B方法的不再是代理對象而是目標(biāo)對象,故B方法不會被代理
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java中YYYY-MM-dd與yyyy-MM-dd的區(qū)別及跨年問題
YYYY-MM-dd可能會導(dǎo)致跨年周的日期被歸屬到錯誤的年份, yyyy-MM-dd總是表示實際的日歷年份,無論日期所在的周是否跨年,本文就來介紹一下兩者的區(qū)別,感興趣的可以了解一下2024-01-01
使用java數(shù)組 封裝自己的數(shù)組操作示例
這篇文章主要介紹了使用java數(shù)組 封裝自己的數(shù)組操作,結(jié)合實例形式分析了java數(shù)組索引、遍歷等相關(guān)封裝操作技巧與注意事項,需要的朋友可以參考下2020-03-03
Java實現(xiàn)將數(shù)組的元素用逗號連接的多種方法
在 Java 開發(fā)中,我們經(jīng)常需要將數(shù)組中的元素用逗號連接成一個字符串,這種需求在日志記錄、數(shù)據(jù)導(dǎo)出、API 響應(yīng)等場景中非常常見,本文將詳細(xì)介紹如何在 Java 中實現(xiàn)這一功能,并提供多種簡潔的方法和優(yōu)化建議,需要的朋友可以參考下2025-01-01
Java運(yùn)行時數(shù)據(jù)區(qū)概述詳解
這篇文章主要介紹了Java運(yùn)行時數(shù)據(jù)區(qū)概述,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03

