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通知细节-避坑指南的主要内容,如果未能解决你的问题,请参考以下文章