Spring AOP源码解析:执行切面

请添加图片描述

切面执行顺序

说起这个切面执行顺序,我就想起一个之前遇到的挺有意思的问题,为啥@Around方法里面不手动调用joinPoint.proceed()方法,目标方法就不会执行,并且@Before方法的逻辑也不会执行?

我们先来看一下切面的执行顺序

一个方法被一个aspect类拦截时的执行顺序如下

@Around->@Before->方法执行->@Around->@After->@AfterReturning/@AfterThrowing

当方法正常结束时,执行@AfterReturning。方法异常结束时,执行@AfterThrowing

在这里插入图片描述
当多个切面同时执行时,我们可以实现Ordered接口,或者使用@Order注解指定顺序。order值越小,执行顺序越来越靠前

在这里插入图片描述
图中After,AfterReturning,AfterThrowing还是依次执行哈,放到一块是图片好看一点

JDK动态代理切面执行

在这里插入图片描述
我们只分析JdkDynamicAopProxy的执行过程,jdk动态代理的类所有方法的执行都会经过InvocationHandler#invoke方法,所以我们直接来分析invoker方法

JdkDynamicAopProxy#invoke(省略部分无关紧要的逻辑)
在这里插入图片描述
之前在生成代理对象的时候,我们把能够应用于当前Bean的Advisor存到advised,当方法执行的时候执行getInterceptorsAndDynamicInterceptionAdvice方法筛选出能够适用于当前方法的Advisor,并缓存下来

AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice
在这里插入图片描述
如果方法没有对应的Advisor,则反射执行方法即可
如果方法有对应的Advisor,则执行ReflectiveMethodInvocation#proceed

ReflectiveMethodInvocation#proceed
在这里插入图片描述
感觉切面链念起来怪怪的,我们这里就叫做拦截器链把,这段的作用主要就是依次执行拦截器链然后执行目标方法。如果拦截器是InterceptorAndDynamicMethodMatcher的实现类,则动态匹配一下,看是否需要执行。

我们常用的AspectJ注解都是直接强转为MethodInterceptor,然后执行invoke方法。

我原来看到这段代码的时候还挺奇怪的,拦截器链执行完才执行被代理的方法,那@Around,@After之类的拦截器是怎么执行的?不应该放在目标方法执行完毕才执行吗?

于是写了如下一个Demo,把所有的拦截器都用上
在这里插入图片描述
执行的时候拦截器的顺序如下,
在这里插入图片描述
ExposeInvocationInterceptor是框架设置进去的,不管他了。我把调用的链路画了一下,这样所以的疑惑都解决了,源码我就不看了哈,简单的递归调用
在这里插入图片描述
图示中的proceed代表执行ReflectiveMethodInvocation#proceed方法哈

看到图示你应该明白了@Around里面不调用joinPoint.proceed()方法时,目标方法和@Before逻辑都不会执行的原因了把!

参考博客

[1]https://www.tianxiaobo.com/2018/06/22/Spring-AOP-%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90-%E6%8B%A6%E6%88%AA%E5%99%A8%E9%93%BE%E7%9A%84%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B/
好文
[2]https://www.cnblogs.com/lifullmoon/p/14654883.html
顺序
[1]https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop-ataspectj-advice-ordering
[2]https://www.cnblogs.com/csyh/articles/13246574.html
好文
[3]https://juejin.cn/post/6844903975578238984
[4]https://blog.csdn.net/nickyyu/article/details/105027203
[5]https://zhuanlan.zhihu.com/p/373973937
[6]https://www.cnblogs.com/tomakemyself/p/14131421.html
[7]https://my.oschina.net/u/2377110/blog/1536991

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java识堂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值