# 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逻辑都不会执行的原因了把!