溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何解決SpringAop內(nèi)部調(diào)用時(shí)不經(jīng)過代理類的問題

發(fā)布時(shí)間:2022-01-04 00:32:07 來源:億速云 閱讀:165 作者:柒染 欄目:開發(fā)技術(shù)

如何解決SpringAop內(nèi)部調(diào)用時(shí)不經(jīng)過代理類的問題,針對這個(gè)問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。

SpringAop

AOP代理織入時(shí)期

  • 編譯時(shí)織入 - aspectj框架

  • 類加載時(shí)織入 - aspectj框架

  • 運(yùn)行時(shí)織入 - spring-aop

動(dòng)態(tài)代理方式

  • JDK - 被代理對象必須需要實(shí)現(xiàn)接口

  • CGLIB - 采用繼承被代理對象方式實(shí)現(xiàn)代理功能

解決SpringAop內(nèi)部調(diào)用時(shí)不經(jīng)過代理類(而是通過this)

方案一

通過編譯時(shí)織入或者類加載時(shí)織入代碼

方案二

通過當(dāng)前代理類調(diào)用目標(biāo)方法

getOne()方法中直接調(diào)用getAll()時(shí)是通過this對象,這時(shí)候getAll()方法上的@AopLog就不會(huì)被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()方法,這時(shí)候就是通過代理類調(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兩個(gè)方法,A方法中調(diào)用了B方法,執(zhí)行A方法時(shí),B方法的代理沒有生效

問題剖析

我們知道AOP底層使用JDK動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理想結(jié)合,通過判斷去創(chuàng)建對應(yīng)的代理對象。

而不管是那種方法,最終執(zhí)行完代理后,都會(huì)執(zhí)行目標(biāo)方法:method.invoke(target,agrs)-->傳入目標(biāo)對象

所以執(zhí)行A方法的代理后,執(zhí)行A的目標(biāo)方法,此時(shí)執(zhí)行的對象是目標(biāo)對象,所以目標(biāo)對象執(zhí)行A方法是A中隱藏的this

指的就是目標(biāo)對象,即執(zhí)行B方法的不再是代理對象而是目標(biāo)對象,故B方法不會(huì)被代理

關(guān)于如何解決SpringAop內(nèi)部調(diào)用時(shí)不經(jīng)過代理類的問題問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI