【Spring】AOP实现原理(三):创建代理(基于注解)

AbstractAutoProxyCreator

在AbstractAutoProxyCreator的wrapIfNecessary方法中,调用getAdvicesAndAdvisorsForBean方法获取到所有的Advisor之后,就可以创建代理对象了,创建的具体过程在createProxy方法中:

  1. 创建代理工厂ProxyFactory
  2. 调用buildAdvisors构建Advisor,入参是getAdvicesAndAdvisorsForBean获取到的Advice和Advisor,里面又调用了AdvisorAdapterRegistry的wrap方法判断Advice是否是Advisor类型,这一步主要是对通知Advice进行校验,如果通知不是Advisor类型将其包装为Advisor
  3. 通过代理工厂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
    72
    public 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
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
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

// 调用GlobalAdvisorAdapterRegistry的getInstance获取AdvisorAdapterRegistry实例
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();

/**
* 构建Advisors,specificInterceptors是上一步获取到的Advice和Advisor
*/
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// Handle prototypes correctly...
Advisor[] commonInterceptors = resolveInterceptorNames();

List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
// 将获取到的Advice和Advisor添加到拦截器中
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors.length > 0) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
if (logger.isTraceEnabled()) {
int nrOfCommonInterceptors = commonInterceptors.length;
int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
}
// 创建Advisor集合
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
// 调用AdvisorAdapterRegistry的wrap方法将通知包装为Advisor进行增强,在DefaultAdvisorAdapterRegistry中实现
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}

}

AdvisorAdapterRegistry

在GlobalAdvisorAdapterRegistry中可以看到使用的是DefaultAdvisorAdapterRegistry:

1
2
3
4
5
6
7
8
9
10
11
12
13
public final class GlobalAdvisorAdapterRegistry {
/**
* 使用DefaultAdvisorAdapterRegistry
*/
private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();

/**
* 返回AdvisorAdapterRegistry
*/
public static AdvisorAdapterRegistry getInstance() {
return instance;
}
}

DefaultAdvisorAdapterRegistry

DefaultAdvisorAdapterRegistry中的wrap方法主要逻辑如下:

  1. 如果当前的通知已经是Advisor类型直接返回即可
  2. 如果当前的通知不是Advice类型,抛出异常
  3. 将通知转为Advice,对通知进行判断
    • 如果通知是MethodInterceptor方法拦截器,将其包装为DefaultPointcutAdvisor
    • 如果不是MethodInterceptor,遍历Adapter适配器,找出支持当前通知的适配器,再将通知包装为DefaultPointcutAdvisor返回
  4. 非以上几种情况抛出异常
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
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
// 如果已经是Advisor,返回即可
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
// 如果不是Advice类型,抛出异常
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
// 转为Advice
Advice advice = (Advice) adviceObject;
// 如果是一个方法拦截器
if (advice instanceof MethodInterceptor) {
// 包装为DefaultPointcutAdvisor
return new DefaultPointcutAdvisor(advice);
}
for (AdvisorAdapter adapter : this.adapters) {
// 判断Advisor适配器是否支持当前的Advice
if (adapter.supportsAdvice(advice)) {
// 包装为DefaultPointcutAdvisor
return new DefaultPointcutAdvisor(advice);
}
}
// 抛出异常
throw new UnknownAdviceTypeException(advice);
}
}

生成代理对象

上一步中已经对所有的Advice进行了校验,转为了Advisor进行增强,接下来就可以生成代理对象了,具体实现在ProxyFactory的getProxy中:

  1. 调用createAopProxy获取AopProxy,AopProxy是一个接口,定义了getProxy获取代理对象的方法,它有两个实现类分别为CglibAopProxyJdkDynamicAopProxy

  2. 调用AopProxy的getProxy方法获取代理对象

1
2
3
4
5
6
7
8
9
10
public class ProxyFactory extends ProxyCreatorSupport {
/**
* 获取代理对象
*/
public Object getProxy(@Nullable ClassLoader classLoader) {
// 通过工厂创建AOP代理对象,createAopProxy方法在ProxyCreatorSupport中实现
return createAopProxy().getProxy(classLoader);
}

}

createAopProxy创建AopProxy

createAopProxy的实现逻辑在ProxyFactory的父类ProxyCreatorSupport中实现,它使用了工厂模式生成代理对象:

  1. 调用getAopProxyFactory方法获取AopProxyFactory,在无参构造函数中可以看的默认使用的工厂是DefaultAopProxyFactory
  2. 调用AopProxyFactory的createAopProxy方法创建代理对象
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
// ProxyCreatorSupport
public class ProxyCreatorSupport extends AdvisedSupport {

// AOP代理工厂
private AopProxyFactory aopProxyFactory;

/**
* 无参构造函数
*/
public ProxyCreatorSupport() {
// 工厂的实现默认使用DefaultAopProxyFactory
this.aopProxyFactory = new DefaultAopProxyFactory();
}

/**
* 带有AopProxyFactory参数的构造函数
*/
public ProxyCreatorSupport(AopProxyFactory aopProxyFactory) {
Assert.notNull(aopProxyFactory, "AopProxyFactory must not be null");
this.aopProxyFactory = aopProxyFactory;
}

/**
* 创建AopProxy
*/
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// 1.调用getAopProxyFactory获取AopProxy,2.调用AopProxy的createAopProxy创建代理对象
return getAopProxyFactory().createAopProxy(this);
}

/**
* 返回AOP代理工厂
*/
public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}
}

DefaultAopProxyFactory

DefaultAopProxyFactory中创建AOP代理的逻辑如下:

  1. 获取目标对象的Class信息
  2. 对Class进行判断:
    • 如果是一个接口或者isProxyClass返回true使用JDK动态代理生成代理对象,isProxyClass方法在JDK的Proxy中实现,返回true的条件为目标类是java.lang.reflect.Proxy的子类并且缓存中包含目标类
    • 如果上一个条件不满足则使用CGLIB生成代理对象
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
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
// 获取目标对象的Class信息
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
// 如果是一个接口
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 否则使用CGLIB生成代理对象
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
}

// java.lang.reflect.Proxy
public class Proxy implements java.io.Serializable {

public static boolean isProxyClass(Class<?> cl) {
// 是否是java.lang.reflect.Proxy的子类并且缓存中包含目标类
return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
}
}

到此AopProxy已经创建成功,接下来以JdkDynamicAopProxy为例查看getProxy获取代理对象过程。

getProxy获取代理对象

JdkDynamicAopProxy是通过JDK的动态代理实现代理创建的,可以看到它实现了InvocationHandler接口,关于JDK的动态代理实现原理可参考【JAVA】动态代理,这里我们需要关注getProxy和invoke方法:

  • getProxy:创建代理对象
  • invoke:当代理对象中引用的方法执行时会进入这个方法中
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
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {

@Override
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 生成代理对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 先省略

}
}

getProxy创建代理对象

可以看到是通过JDK中Proxy的newProxyInstance生成代理对象的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 生成代理对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
}

invoke方法

当调用AOP中需要被通知拦截的方法时,会进入到invoke方法,比较核心的是getInterceptorsAndDynamicInterceptionAdvice获取拦截器链,如果为空直接通过反射执行目标方法即可,如果不为空,将方法包装为MethodInvocation,然后执行拦截器链

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {

/** AdvisedSupport */
private final AdvisedSupport advised;

/**
* InvocationHandler中定义的invoke方法,当目标方法执行时会进入到这个方法中
* @param proxy 代理对象
* @param method 需要被执行的目标方法
* @param args
* @return
* @throws Throwable
*/
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;

TargetSource targetSource = this.advised.targetSource;
Object target = null;

try {
// 如果是equals方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// 如果是hashCode方法
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// 如果方法所在类是DecoratingProxy类
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}

Object retVal;
// 是否需要暴露代理
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);

// 获取当前方法的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

// 校验拦截器链是否为空
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 如果为空直接执行目标方法即可
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 创建MethodInvocation
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 执行拦截器链
retVal = invocation.proceed();
}

// 获取方法返回值
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
}

获取方法的拦截器链

获取目标方法的拦截器链在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
21
public 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进行判断:

  1. 如果是PointcutAdvisor类型,将Advisor转为PointcutAdvisor,然后获取Pointcut切点的ClassFilter,通过matches方法判断当前方法所属的class是否匹配,如果匹配,则从切点中获取MethodMatcher方法匹配器,调用它的matches方法判断切点与当前方法是否匹配,如果也匹配,调用AdvisorAdapterRegistry的getInterceptors将Advisor转为方法拦截器

  2. 如果是引入通知IntroductionAdvisor,并且ClassFilter的matches与当前类匹配,调用AdvisorAdapterRegistry的getInterceptors将Advisor转为方法拦截器

  3. 非以上两种情况,调用AdvisorAdapterRegistry的getInterceptors将Advisor转为方法拦截器

可以看到以上三种情况,最后都是调用了AdvisorAdapterRegistry获取拦截器的,接下来就进入AdvisorAdapterRegistry中查看getInterceptors的具体实现。

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
public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {
/**
* 获取方法的拦截器链
*/
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {

// 获取AdvisorAdapterRegistry
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
// 获取Advisor
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
// 遍历Advisor
for (Advisor advisor : advisors) {
// 如果是PointcutAdvisor类型
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// 调用matches方法判断与当前class是否匹配
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
// 获取方法匹配器MethodMatcher
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
// 如果是IntroductionAwareMethodMatcher
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
// 调用MethodMatcher的matches方法匹配
match = mm.matches(method, actualClass);
}
if (match) {
// 如果匹配,从registry中获取方法拦截器
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
// 将拦截器封装为InterceptorAndDynamicMethodMatcher
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
// 如果是引入通知IntroductionAdvisor
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}

return interceptorList;
}
}

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
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
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {

private final List<AdvisorAdapter> adapters = new ArrayList<>(3);

/**
* 注册AdvisorAdapter
*/
public DefaultAdvisorAdapterRegistry() {
// 注册MethodBeforeAdviceAdapter
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
// 注册AfterReturningAdviceAdapter
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
// 注册ThrowsAdviceAdapter
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}

@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
// 从Advisor中获取Advice
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
// 遍历Adapter
for (AdvisorAdapter adapter : this.adapters) {
// 判断是否支持当前的通知
if (adapter.supportsAdvice(advice)) {
// 通过Adapter获取拦截器
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}
}

AdvisorAdapter有三个实现类,以MethodBeforeAdviceAdapter为例查看一下supportsAdvice和getInterceptor的实现:

  1. 在supportsAdvice方法中可以看到它支持的是MethodBeforeAdvice方法前置通知

  2. 在getInterceptor方法中,首先从Advisor中获取到了通知,然后将通知封装为MethodBeforeAdviceInterceptor返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {

@Override
public boolean supportsAdvice(Advice advice) {
// 是否是MethodBeforeAdvice类型
return (advice instanceof MethodBeforeAdvice);
}

@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
// 封装为MethodBeforeAdviceInterceptor
return new MethodBeforeAdviceInterceptor(advice);
}

}

执行目标方法

回顾invoke方法中的主要逻辑,在获取到方法的拦截器之后,对拦截器是否为空进行了判断:

  • 如果为空,调用AopUtils的invokeJoinpointUsingReflection通过反射直接执行方法即可

  • 如果不为空创建MethodInvocation,具体实现类是ReflectiveMethodInvocation,然后调用proceed执行拦截器链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

// 获取当前方法的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

// 校验拦截器链是否为空
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 如果为空直接执行目标方法即可
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} else {
// 创建MethodInvocation,使用的是ReflectiveMethodInvocation类型
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 执行拦截器链
retVal = invocation.proceed();
}

invokeJoinpointUsingReflection

invokeJoinpointUsingReflection方法通过反射执行目标方法,在AopUtils中实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public abstract class AopUtils {

@Nullable
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
throws Throwable {

// 通过反射执行目标方法
try {
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
method + "] on target [" + target + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopInvocationException("Could not access method [" + method + "]", ex);
}
}

}

proceed方法执行拦截器链

因为拦截器可以有多个,所以proceed方法是一个递归调用的过程,currentInterceptorIndex记录了当前拦截器的下标:

  1. 判断currentInterceptorIndex是否与拦截器链的大小一致,如果一致说明已经走到了最后一个拦截器,调用invokeJoinpoint方法执行目标方法即可,可以看到调用了AopUtils的invokeJoinpointUsingReflection通过反射执行目标方法,如果不是最后一个拦截器进入第2步
  2. 对currentInterceptorIndex++,获取下一个拦截器,判断拦截器是否是InterceptorAndDynamicMethodMatcher类型,如果是获取methodMatcher对目标方法进行匹配:
    • 如果与目标方法匹配成功,执行拦截器的invoke方法
    • 如果与目标方法匹配不成功,递归调用proceed方法执行下一个拦截器
  3. 如果拦截器不是InterceptorAndDynamicMethodMatcher类型,直接调用方法拦截器MethodInterceptor的invoke执行拦截器即可

在执行MethodInterceptor方法拦截器的invoke方法时,传入的参数是this,指的是ReflectiveMethodInvocation对象本身,在拦截器方法执行后需要拿到这个对象调用proceed方法继续执行下一个拦截器,可以看到这里使用了责任链模式,对拦截器进行一个个的调用。

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
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
@Override
@Nullable
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
// 执行方法
return invokeJoinpoint();
}
// 获取下一个拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// 如果是InterceptorAndDynamicMethodMatcher
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
// 判断方法是否匹配
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// 如果方法不匹配,跳过当前拦截器执行下一个,递归调用
return proceed();
}
}
else {
// 转为MethodInterceptor执行拦截器,注意invoke传入的参数是this,指的是ReflectiveMethodInvocation对象本身,在拦截器的invoke方法中需要拿到这个对象调用proceed方法继续执行下一个拦截器
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}

/**
* 通过反射执行目标方法
*/
@Nullable
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}

}

MethodBeforeAdviceInterceptor

以前置通知为例,看一下MethodBeforeAdviceInterceptor拦截器中的invoke方法的执行逻辑:

  1. 前置通知是在目标方法执行之前执行的方法,所以先调用了invokeAdviceMethod执行了前置通知方法
  2. 调用MethodInvocation的proceed执行下一个拦截器链,在上一步中可以看到调用拦截器时传入的是this,this指向ReflectiveMethodInvocation,所以会继续执行到它的proceed方法,继续下一个拦截器的执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 先执行通知方法,在AspectJMethodBeforeAdvice中实现
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
// 执行拦截器链,这里调用的是MethodInvocation的proceed方法,会再次进入到ReflectiveMethodInvocation的proceed方法中
return mi.proceed();
}

}
// AspectJMethodBeforeAdvice
public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice, Serializable {
@Override
public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
// 执行通知方法
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}

AspectJAroundAdvice

再以环绕通知为例,看一下环绕通知的执行逻辑,AspectJAroundAdvice实现了MethodInterceptor接口,所以它本身就是一个拦截器,在invoke方法中它调用了invokeAdviceMethod执行通知方法,并将ReflectiveMethodInvocation转换为ProceedingJoinPoint,在环绕通知中通过ProceedingJoinPoint调用proceed方法执行下一个拦截器

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
public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
// mi是上一步中传入的ReflectiveMethodInvocation,这里将其转换为ProxyMethodInvocation
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
// 将ProxyMethodInvocation转为ProceedingJoinPoint
ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
JoinPointMatch jpm = getJoinPointMatch(pmi);
// 执行通知方法
return invokeAdviceMethod(pjp, jpm, null, null);
}
}

@SuppressWarnings("serial")
public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedenceInformation, Serializable {
/**
* 执行通知方法
*/
protected Object invokeAdviceMethod(JoinPoint jp, @Nullable JoinPointMatch jpMatch,
@Nullable Object returnValue, @Nullable Throwable t) throws Throwable {
// 通过给定的参数执行通知方法
return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t));
}
/**
* 通过给定的参数执行通知方法
*/
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
Object[] actualArgs = args;
if (this.aspectJAdviceMethod.getParameterCount() == 0) {
actualArgs = null;
}
try {
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
// 这里执行了通知方法,接下来会进入到定义的环绕通知方法中
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("Mismatch on arguments to advice method [" +
this.aspectJAdviceMethod + "]; pointcut expression [" +
this.pointcut.getPointcutExpression() + "]", ex);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}

假设定义了如下的环绕通知,在环绕通知方法被执行时,会进入到logAroudAdvice方法中,可以看到先打印了方法执行前的日志,然后调用了ProceedingJoinPoint的proceed方法执行拦截器链,上一步可知ProceedingJoinPoint是MethodInvocation转换而来,所以又会进入到ReflectiveMethodInvocation的proceed方法执行下一个拦截器链,待所有的拦截器执行完毕后proceed方法也就结束,然后执行了printAfterLog打印方法执行后的日志:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 通知Advice,这里使用了环绕通知
* @param joinPoint 连接点
* @return
* @throws Throwable
*/
@Around("logPoiontcut()") // 引用切点
public Object logAroudAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
// 方法执行前的日志打印
printBeforeLog(joinPoint);
// 执行拦截器链
Object returnValue = joinPoint.proceed();
// 方法执行后的日志打印
printAfterLog(returnValue);
return returnValue;
}

总结

方法拦截器链的执行流程图

AOP总结

参考

【猫吻鱼】Spring源码分析:全集整理

Spring版本:5.2.5.RELEASE