AbstractAutoProxyCreator
在AbstractAutoProxyCreator的wrapIfNecessary方法中,调用getAdvicesAndAdvisorsForBean方法获取到所有的Advisor之后,就可以创建代理对象了,创建的具体过程在createProxy方法中:
- 创建代理工厂ProxyFactory
- 调用buildAdvisors构建Advisor,入参是getAdvicesAndAdvisorsForBean获取到的Advice和Advisor,里面又调用了AdvisorAdapterRegistry的wrap方法判断Advice是否是Advisor类型,这一步主要是对通知Advice进行校验,如果通知不是Advisor类型将其包装为Advisor
- 通过代理工厂ProxyFactory生成代理对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
/**
* 是否有必要生成代理对象
* @param bean
* @param beanName
* @param cacheKey
* @return
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 获取Advices和Advisors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理,specificInterceptors就是获取到的Advices和Advisors
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
/**
* 创建代理对象
*/
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 1.创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 2.构建Advisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 设置Advisor
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 3.生成代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
}
构建Advisor
AbstractAutoProxyCreator的buildAdvisors主要是对通知Advice进行校验,如果通知不是Advisor类型将其包装为Advisor,具体是通过AdvisorAdapterRegistry的wrap方法实现的:
1 | public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport |
AdvisorAdapterRegistry
在GlobalAdvisorAdapterRegistry中可以看到使用的是DefaultAdvisorAdapterRegistry:
1 | public final class GlobalAdvisorAdapterRegistry { |
DefaultAdvisorAdapterRegistry
DefaultAdvisorAdapterRegistry中的wrap方法主要逻辑如下:
- 如果当前的通知已经是Advisor类型直接返回即可
- 如果当前的通知不是Advice类型,抛出异常
- 将通知转为Advice,对通知进行判断
- 如果通知是MethodInterceptor方法拦截器,将其包装为DefaultPointcutAdvisor
- 如果不是MethodInterceptor,遍历Adapter适配器,找出支持当前通知的适配器,再将通知包装为DefaultPointcutAdvisor返回
- 非以上几种情况抛出异常
1 | public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable { |
生成代理对象
上一步中已经对所有的Advice进行了校验,转为了Advisor进行增强,接下来就可以生成代理对象了,具体实现在ProxyFactory的getProxy中:
调用createAopProxy获取AopProxy,AopProxy是一个接口,定义了getProxy获取代理对象的方法,它有两个实现类分别为CglibAopProxy和JdkDynamicAopProxy
调用AopProxy的getProxy方法获取代理对象
1 | public class ProxyFactory extends ProxyCreatorSupport { |
createAopProxy创建AopProxy
createAopProxy的实现逻辑在ProxyFactory的父类ProxyCreatorSupport中实现,它使用了工厂模式生成代理对象:
- 调用getAopProxyFactory方法获取AopProxyFactory,在无参构造函数中可以看的默认使用的工厂是DefaultAopProxyFactory
- 调用AopProxyFactory的createAopProxy方法创建代理对象
1 | // ProxyCreatorSupport |
DefaultAopProxyFactory
DefaultAopProxyFactory中创建AOP代理的逻辑如下:
- 获取目标对象的Class信息
- 对Class进行判断:
- 如果是一个接口或者isProxyClass返回true使用JDK动态代理生成代理对象,isProxyClass方法在JDK的Proxy中实现,返回true的条件为目标类是java.lang.reflect.Proxy的子类并且缓存中包含目标类
- 如果上一个条件不满足则使用CGLIB生成代理对象
1 | public class DefaultAopProxyFactory implements AopProxyFactory, Serializable { |
到此AopProxy已经创建成功,接下来以JdkDynamicAopProxy为例查看getProxy获取代理对象过程。
getProxy获取代理对象
JdkDynamicAopProxy是通过JDK的动态代理实现代理创建的,可以看到它实现了InvocationHandler接口,关于JDK的动态代理实现原理可参考【JAVA】动态代理,这里我们需要关注getProxy和invoke方法:
- getProxy:创建代理对象
- invoke:当代理对象中引用的方法执行时会进入这个方法中
1 | final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable { |
getProxy创建代理对象
可以看到是通过JDK中Proxy的newProxyInstance生成代理对象的:
1 |
|
invoke方法
当调用AOP中需要被通知拦截的方法时,会进入到invoke方法,比较核心的是getInterceptorsAndDynamicInterceptionAdvice获取拦截器链,如果为空直接通过反射执行目标方法即可,如果不为空,将方法包装为MethodInvocation,然后执行拦截器链:
1 | final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable { |
获取方法的拦截器链
获取目标方法的拦截器链在AdvisedSupport中实现,它主要用于将适用于当前方法的Advisor转为方法拦截器,首先它先从缓存中查询,如果未查询到,调用advisorChainFactory方法的getInterceptorsAndDynamicInterceptionAdvice进行获取,在DefaultAdvisorChainFactory中实现:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public class AdvisedSupport extends ProxyConfig implements Advised {
/** AdvisorChainFactory,默认使用DefaultAdvisorChainFactory*/
AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();
/**
* 获取方法的拦截器链
*/
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
// 构建缓存KEY
MethodCacheKey cacheKey = new MethodCacheKey(method);
// 从缓存获取
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
// 如果未从缓存中获取到,调用getInterceptorsAndDynamicInterceptionAdvice获取方法的拦截器链
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
// 加入到缓存
this.methodCache.put(cacheKey, cached);
}
return cached;
}
}
DefaultAdvisorChainFactory
getInterceptorsAndDynamicInterceptionAdvice中先获取了所有的Advisor,然后遍历Advisor,对Advisor进行判断:
如果是PointcutAdvisor类型,将Advisor转为PointcutAdvisor,然后获取Pointcut切点的ClassFilter,通过matches方法判断当前方法所属的class是否匹配,如果匹配,则从切点中获取MethodMatcher方法匹配器,调用它的matches方法判断切点与当前方法是否匹配,如果也匹配,调用AdvisorAdapterRegistry的getInterceptors将Advisor转为方法拦截器
如果是引入通知IntroductionAdvisor,并且ClassFilter的matches与当前类匹配,调用AdvisorAdapterRegistry的getInterceptors将Advisor转为方法拦截器
- 非以上两种情况,调用AdvisorAdapterRegistry的getInterceptors将Advisor转为方法拦截器
可以看到以上三种情况,最后都是调用了AdvisorAdapterRegistry获取拦截器的,接下来就进入AdvisorAdapterRegistry中查看getInterceptors的具体实现。
1 | public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable { |
DefaultAdvisorAdapterRegistry
在DefaultAdvisorAdapterRegistry的构造函数中注册了三种AdvisorAdapter,使用了适配器模式将Advisor转换为方法拦截器MethodInterceptor,三种AdvisorAdapter分别为:
- MethodBeforeAdviceAdapter:支持前置通知MethodBeforeAdvice
- AfterReturningAdviceAdapter:支持返回通知AfterReturningAdvice
- ThrowsAdviceAdapter:支持ThrowsAdvice
AspectJAfterThrowingAdvice、AspectJAroundAdvice和AspectJAfterAdvice本身已经实现了MethodInterceptor接口,所以不需要进行转换:
在getInterceptors方法中,对Advisor进行判断,如果本身已经是MethodInterceptor直接返回即可,否则遍历所有的AdvisorAdapter,找出支持当前Advisor的Adapter,然后将Advisor转为MethodInterceptor:
1 | public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable { |
AdvisorAdapter有三个实现类,以MethodBeforeAdviceAdapter为例查看一下supportsAdvice和getInterceptor的实现:
在supportsAdvice方法中可以看到它支持的是MethodBeforeAdvice方法前置通知
在getInterceptor方法中,首先从Advisor中获取到了通知,然后将通知封装为MethodBeforeAdviceInterceptor返回
1 | class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable { |
执行目标方法
回顾invoke方法中的主要逻辑,在获取到方法的拦截器之后,对拦截器是否为空进行了判断:
如果为空,调用AopUtils的invokeJoinpointUsingReflection通过反射直接执行方法即可
如果不为空创建MethodInvocation,具体实现类是ReflectiveMethodInvocation,然后调用proceed执行拦截器链
1 |
|
invokeJoinpointUsingReflection
invokeJoinpointUsingReflection方法通过反射执行目标方法,在AopUtils中实现:
1 | public abstract class AopUtils { |
proceed方法执行拦截器链
因为拦截器可以有多个,所以proceed方法是一个递归调用的过程,currentInterceptorIndex记录了当前拦截器的下标:
- 判断currentInterceptorIndex是否与拦截器链的大小一致,如果一致说明已经走到了最后一个拦截器,调用invokeJoinpoint方法执行目标方法即可,可以看到调用了AopUtils的invokeJoinpointUsingReflection通过反射执行目标方法,如果不是最后一个拦截器进入第2步
- 对currentInterceptorIndex++,获取下一个拦截器,判断拦截器是否是InterceptorAndDynamicMethodMatcher类型,如果是获取methodMatcher对目标方法进行匹配:
- 如果与目标方法匹配成功,执行拦截器的invoke方法
- 如果与目标方法匹配不成功,递归调用proceed方法执行下一个拦截器
- 如果拦截器不是InterceptorAndDynamicMethodMatcher类型,直接调用方法拦截器MethodInterceptor的invoke执行拦截器即可
在执行MethodInterceptor方法拦截器的invoke方法时,传入的参数是this,指的是ReflectiveMethodInvocation对象本身,在拦截器方法执行后需要拿到这个对象调用proceed方法继续执行下一个拦截器,可以看到这里使用了责任链模式,对拦截器进行一个个的调用。
1 | public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable { |
MethodBeforeAdviceInterceptor
以前置通知为例,看一下MethodBeforeAdviceInterceptor拦截器中的invoke方法的执行逻辑:
- 前置通知是在目标方法执行之前执行的方法,所以先调用了invokeAdviceMethod执行了前置通知方法
- 调用MethodInvocation的proceed执行下一个拦截器链,在上一步中可以看到调用拦截器时传入的是this,this指向ReflectiveMethodInvocation,所以会继续执行到它的proceed方法,继续下一个拦截器的执行
1 | public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable { |
AspectJAroundAdvice
再以环绕通知为例,看一下环绕通知的执行逻辑,AspectJAroundAdvice实现了MethodInterceptor接口,所以它本身就是一个拦截器,在invoke方法中它调用了invokeAdviceMethod执行通知方法,并将ReflectiveMethodInvocation转换为ProceedingJoinPoint,在环绕通知中通过ProceedingJoinPoint调用proceed方法执行下一个拦截器:
1 | public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable { |
假设定义了如下的环绕通知,在环绕通知方法被执行时,会进入到logAroudAdvice方法中,可以看到先打印了方法执行前的日志,然后调用了ProceedingJoinPoint的proceed方法执行拦截器链,上一步可知ProceedingJoinPoint是MethodInvocation转换而来,所以又会进入到ReflectiveMethodInvocation的proceed方法执行下一个拦截器链,待所有的拦截器执行完毕后proceed方法也就结束,然后执行了printAfterLog打印方法执行后的日志:
1 | /** |
总结
方法拦截器链的执行流程图
AOP总结
参考
Spring版本:5.2.5.RELEASE