鍍金池/ 問答/Java/ spring aop中的前置通知

spring aop中的前置通知

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

    <property name="beanNames">
        <list>
            <value>fixassetService</value><!-- 添加需要攔截的service bean-->
        </list>
    </property>

    <property name="interceptorNames">
        <list>
            <value>myInterceptor</value>
            <value>myInterceptor2</value>
        </list>
     
    </property>
</bean>


在上面的配置文件中 我配置了兩個interceptor ,這兩個interceptor的invoke方法中的邏輯是一樣的。
public Object invoke(MethodInvocation invo) throws Throwable {

//自己的橫切邏輯
log....
invo.proceed()

}

我想請教的問題是,在 第一個interceptor的invoke執(zhí)行的時候 會執(zhí)行內(nèi)部的invo.proceed()方法,這個方法本質(zhì)就是我們joinpoint所表示的方法(或者說被插入橫切邏輯的方法),而當(dāng)interceptor2執(zhí)行invoke方法的 時候又會 執(zhí)行interceptor2 的invoke方法,同時也就再次執(zhí)行invo.proceed() 這樣 不就導(dǎo)致 joinpoint所表示的方法執(zhí)行了兩次?

請問 我的理解對嗎

回答
編輯回答
魚梓

并不是這樣的,實際上兩個代理通知之間的執(zhí)行關(guān)系不是順序關(guān)系,而是嵌套關(guān)系。
你的理解是生成代理類執(zhí)行的關(guān)系是:

// 先執(zhí)行myInterceptor的invoke方法
myInterceptor.before();
myInterceptor.proceed();
myInterceptor.after();
// 再執(zhí)行myInterceptor2的invoke方法
myInterceptor2.before();
myInterceptor2.invoke();
myInterceptor2.after();

這樣邏輯顯然是不對的
實際上執(zhí)行順序應(yīng)該為:

myInterceptor.before();
myInterceptor2.before();
method.proceed(); // 執(zhí)行目標(biāo)方法
myInterceptor2.after();
myInterceptor.after();

這是一種嵌套關(guān)系。用通俗的說法理解可以為,你先用myInterceptor代理了你目標(biāo)類,生成了代理類A,再用myInterceptor2代理了代理類A,生成了代理類B。
這時候B的invoke方法就是:

myInterceptor2.before();
A.invoke();
myInterceptor2.after();

B中調(diào)用了A的invoke方法,而A的invoke方法就是:

myInterceptor.before();
method.proceed(); // 執(zhí)行目標(biāo)方法
myInterceptor.after();

這才是實際上AOP執(zhí)行的順序,就不存在你理解的執(zhí)行兩次目標(biāo)方法的問題。

之前我正好有寫到模擬實現(xiàn)spring的AOP的功能,你感興趣可以看看:
實現(xiàn)AOP
引入aspectj實現(xiàn)AOP切點
加強AOP功能

2018年8月11日 23:04