Spring AOP 执行顺序问题

819 阅读3分钟

为什么要讲AOP执行顺序

spring AOP的执行顺序是因为spring版本变化而变化的。所以它并不是一个固定答案而是要带上spring版本一起叙述。

网上有很多关于spring AOP 执行顺序的文章,他们讲得并不是错的而只是过时的,所以就有了这篇文章。

如果想从源码层面了解AOP执行顺序,可以参考我的这篇文章:Spring AOP 动态代理执行流程源码分析

自己在什么时候发现的AOP执行顺序问题

一开始我对spring AOP执行顺序并没有什么太大的疑虑。当我自己使用这springboot2.4.3的时候,AOP的执行顺序是那么正确无误,和我自己心中也想的一样,那就是

around start -> before -> 执行方法 -> afterReturning(afterThrowing)-> after -> around end

直到我在b站看尚硅谷雷丰阳讲的springboot注解驱动开发(AOP原理章节),他是涉及到AOP源码讲解的,思路非常清晰让我对spring AOP有了更深的了解。当我自己尝试去跟源码的时候我发现虽然大体框架上和他讲得大致一样,但是AOP执行的顺序却发生了巨大的变化。

spring AOP在哪个版本执行顺序发生了改变

spring AOP在spring5.2.7版本对AOP执行顺序进行了重大的变化(springboot版本自己参照官网,大概是2.2.5以后)

docs.spring.io/spring-fram…

Snipaste_2022-04-09_10-09-32.png

spring AOP各个版本执行顺序

一层切面

5.2.7之前

image.png

5.2.7之后

Snipaste_2022-04-09_10-11-05.png

两层切面(多层参照两层)

5.2.7之前

Snipaste_2022-04-09_10-02-33.png

5.2.7之后

Snipaste_2022-04-09_10-08-18.png

执行顺序哪里发生了变化

  1. after的执行顺序变到了afterReturning和afterThrowing后面。

  2. around-end的执行顺序由在方法执行结束的后面变到了最后。

为什么AOP的顺序要发生改变

切面发生变化的原因:(针对于执行顺序的变化解释)

1.(官网)当匹配的方法执行退出时最终通知运行。它是通过使用@After注解来声明的。After 通知必须准备好处理正常和异常返回条件。 也就是可以在After中处理返回值和异常,使得代码更加灵活。

2.为什么around-end在最后也是因为现在after在afterReturning和afterThrowing后面,而after中无法返回值 它是在finally代码块中处理数据(下面有截图)若是想要有返回值还是要用around-end也就是around切面是可以有返回值的。(自己理解,如有错误请大佬指正)

现在spring AOP执行顺序在源码中是在哪里看的

在ReflectiveAspectJAdvisorFactory 类中

(其实真的切面执行顺序还是要看代码MethodInterceptor接口的实现类)分别为

AspectJAroundAdvice,MethodBeforeAdviceInterceptor,AspectJAfterAdvice,AfterReturningAdviceInterceptor,AspectJAfterThrowingAdvice中的invoke方法

Snipaste_2022-04-09_11-07-06.png

image.png

致谢

要非常感谢这篇文章的博主 zhuanlan.zhihu.com/p/266111498

我自己在官网上找了很久但是无所收获,还好有这篇文章使我找到了对的地方,再次非常感谢!(虽然他最后的结论有问题)

结尾

这是我对spring AOP执行顺序的理解,以上图片均来自自己的demo正确性可以保证。若有错误请大佬指出,非常感谢!

c3ff758e76ba42399f5473607ebe535b_tplv-k3u1fbpfcp-zoom-in-crop-mark_3024_0_0_0.webp