【Spring源碼】23.AOP之代理執(zhí)行時(shí)@EnableAspectJAutoProxy的exposeProxy屬性有何妙用

1. 前言

前面講到,以JDK動(dòng)態(tài)代理方式 的代理對(duì)象已經(jīng)創(chuàng)建成功,spring中 使用JDK動(dòng)態(tài)代理時(shí),傳入的InvokeHandler是JdkDynamicAopProxy類(lèi)型。

image.png

并且數(shù)據(jù)結(jié)構(gòu)是這樣的

并且他的AdvisedSupport advised 屬性是 proxyFactory{

            advisors :符合該類(lèi)的所有的切面,

            targetSource:被代理目標(biāo)對(duì)象

            proxyTargetClass :代理的方式

}

那么實(shí)現(xiàn)InvokeHandler接口,那么代理對(duì)象調(diào)用方法時(shí),就會(huì)調(diào)入Invoke方法 來(lái)進(jìn)行具體的增強(qiáng)。spring aop的具體代理邏輯就在這個(gè)方法中。


image.png

2. equals和hashCode方法不進(jìn)行代理

首先進(jìn)來(lái)會(huì)取出代理的目標(biāo)對(duì)象,this.advised.targetSource

然后進(jìn)行equals()和hashCode()的判斷,這兩個(gè)方法 是不會(huì)代理的,直接調(diào)用原生方法

image.png

3. @EnableAspectJAutoProxy配置exposeProxy=true,暴露代理對(duì)象

然后如果@EnableAspectJAutoProxy配置的exposeProxy為true的話(huà),

@EnableAspectJAutoProxy(proxyTargetClass = false,exposeProxy = true)

會(huì)將代理對(duì)象提前放入 ThreadLocal里面,供代理過(guò)程中其他地方獲取

image.png

應(yīng)用場(chǎng)景

這個(gè)挺有用的。比如 某個(gè)類(lèi)的 proxyMethodA() 和 proxyMethodB()都會(huì)命中切面,被代理。如果以下面proxyMethodA方法內(nèi)部直接 調(diào)用proxyMethodB()方法,

其實(shí) 調(diào)用的原生對(duì)象的proxyMethodB()方法,是不會(huì)走 proxyMethodB()的代理邏輯的。

@Component
public class ProxyClass implements InterFace {
    public void proxyMethodA() {
        proxyMethodB();
    }

    public void proxyMethodB() {
    }
}

所以,我們要去獲取ProxyClass的代理對(duì)象來(lái)在proxyMethodA()的方法內(nèi)部 調(diào)用proxyMethodB()

注入自己的代理對(duì)象

一種是自己注入自己,那么肯定注入進(jìn)來(lái)的是代理對(duì)象,那么用代理對(duì)象去調(diào)用它的 proxyMethodB()方法,肯定是會(huì)走代理的。

@Component
public class ProxyClass implements MyBeanService {

    @Autowired
    ProxyClass proxyClass;

    public void proxyMethodA() {
        // 注入進(jìn)來(lái)的是 proxyClass代理對(duì)象
        proxyClass.proxyMethodB();
    }
    public void proxyMethodB() {
    }

}

AopContext.currentProxy()

還有一種就是 上面源碼里的AopContext.currentProxy()

會(huì)把代理對(duì)象放入ThreadLocal中,

直接在 proxyMethodA() 方法內(nèi)部AopContext.currentProxy()獲取到代理對(duì)象,然后調(diào)用它的proxyMethodB()

public class ProxyClass implements MyBeanService {

    public void proxyMethodA() {
        Object o = AopContext.currentProxy();
        ((ProxyClass)o).proxyMethodB();
    }

    public void proxyMethodB() {
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容