SpringAOP通知细节-避坑指南

Posted IT老刘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringAOP通知细节-避坑指南相关的知识,希望对你有一定的参考价值。

1.Spring基于XML的通知执行顺序

1.1.XML文件配置说明

图片来源:《Java EE企业级应用开发教程》

1.2.各种通知说明

配置前置通知:在切入点方法执行之前执行
配置后置通知(返回通知):在切入点方法正常执行之后执行。它和异常通知永远只能执行一个
配置异常通知:在切入点方法执行产生异常之后执行。它和后置通知永远只能执行一个
配置最终通知:无论切入点方法是否正常执行,它都会在其后面执行
配置环绕通知:可以在代码中手动控制增强方法何时执行

注意:后置通知和最终通知的区别:后置通知时在方法成功执行后会执行的,如果出现异常就不执行。而最终通知时无论是否出现异常都会执行的,感觉类似于finally

1.3.在配置同一个切入点且不出现异常时的执行顺序

注意,椭圆中顺序不固定,具体顺序与配置文件的申明顺序有关

1.4.情况一

<!--3.2.配置通知-->
 <aop:aspect ref="tx">
     <!--前置通知-->
     <aop:before method="openTx" pointcut-ref="pointcut"/>
     <!--环绕通知-->
     <aop:around method="aroundAdvice" pointcut-ref="pointcut"/>
     <!--后置通知(返回通知)-->
     <aop:after-returning method="CommitTx" pointcut-ref="pointcut" returning="value"/>
     <!--最终通知-->
     <aop:after method="finnallyMethod" pointcut-ref="pointcut"/>
     <!--异常通知-->
     <aop:after-throwing method="Rollback" pointcut-ref="pointcut" throwing="ex"/>
 </aop:aspect>

顺序:

1.2.情况二

<!--3.2.配置通知-->
 <aop:aspect ref="tx">
     <!--环绕通知-->
     <aop:around method="aroundAdvice" pointcut-ref="pointcut"/>
     <!--前置通知-->
     <aop:before method="openTx" pointcut-ref="pointcut"/>
     <!--后置通知(返回通知)-->
     <aop:after-returning method="CommitTx" pointcut-ref="pointcut" returning="value"/>
     <!--最终通知-->
     <aop:after method="finnallyMethod" pointcut-ref="pointcut"/>
     <!--异常通知-->
     <aop:after-throwing method="Rollback" pointcut-ref="pointcut" throwing="ex"/>
 </aop:aspect>

顺序:

结论一:前置通知和环绕通知的顺序和申明顺序有关,申明在前的先执行

1.3.情况三

<aop:aspect ref="tx">
    <!--环绕通知-->
    <aop:around method="aroundAdvice" pointcut-ref="pointcut"/>
    <!--前置通知-->
    <!--<aop:before method="openTx" pointcut-ref="pointcut"/>-->
    <!--后置通知(返回通知)-->
    <aop:after-returning method="CommitTx" pointcut-ref="pointcut" returning="value"/>
    <!--最终通知-->
    <aop:after method="finnallyMethod" pointcut-ref="pointcut"/>
    <!--异常通知-->
    <aop:after-throwing method="Rollback" pointcut-ref="pointcut" throwing="ex"/>
</aop:aspect>

顺序:

1.4.情况四

<aop:aspect ref="tx">
    <!--环绕通知-->
    <aop:around method="aroundAdvice" pointcut-ref="pointcut"/>
    <!--前置通知-->
    <!--<aop:before method="openTx" pointcut-ref="pointcut"/>-->
    <!--最终通知-->
    <aop:after method="finnallyMethod" pointcut-ref="pointcut"/>
    <!--后置通知(返回通知)-->
    <aop:after-returning method="CommitTx" pointcut-ref="pointcut" returning="value"/>
    <!--异常通知-->
    <aop:after-throwing method="Rollback" pointcut-ref="pointcut" throwing="ex"/>
</aop:aspect>

顺序:

1.5.小结

结论:Spring基于XML的申明式通知的执行顺序与配置文件中的申明顺序有关

2.Spring基于注解的通知执行顺序


我们在网上查找关于SpringAop执行顺序的的资料,大多数时候,你会查到如下的答案:

2.1.正常情况

2.2.异常情况

上述测试结果是在Spring的5.2.6.RELEASE版本下进行测试,换成5.2.7.RELEASE版本测试结果就不同了!

2.3.探究顺序错误的真相

于是去官网搜索文档,不得不说Spring由于过于庞大,官网的文档已经到了冗杂的地步,不过最终还是找到了:

https://docs.spring.io/spring-framework/docs/5.2.9.RELEASE/spring-framework-reference/core.html#aop-ataspectj-advice-ordering

As of Spring Framework 5.2.7, advice methods defined in the same @Aspect class that need to run at the same join point are assigned precedence based on their advice type in the following order, from highest to lowest precedence: @Around, @Before, @After, @AfterReturning, @AfterThrowing.

翻译重点:

从Spring5.2.7开始,在相同@Aspect类中,通知方法将根据其类型按照从高到低的优先级进行执行:@Around,@Before ,@After,@AfterReturning,@AfterThrowing。

2.4.结论

经过上面的资料文档查阅,我能给出的结论是:

从Spring5.2.7开始,Spring AOP不再严格按照AspectJ定义的规则来执行advice,而是根据其类型按照从高到低的优先级进行执行:@Around,@Before ,@After,@AfterReturning,@AfterThrowing。

以上是关于SpringAOP通知细节-避坑指南的主要内容,如果未能解决你的问题,请参考以下文章

Android的LitePal数据库ORM使用总结(避坑指南)

Java面试:Java开发者必看避坑指南

.NET AsyncLocal 避坑指南

WSL避坑指南

技术分享 | 避坑指南-无人机自主降落代码解析

增删改查下载-避坑指南