抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

SpringAOP-调用流程

前言

​ 在上篇文章中,我们介绍了 AOP 代理的创建:Spring AOP:创建 AOP 代理,本文将介绍最后的一个重要内容:使用了 AOP 代理的方法的一次完整调用流程。

入口

​ 昨天我们已经讲解了AOP的创建代理对象的过程,我们今天开始讲解AOP的调用过程,我们先从一个测试用例开始

1
2
3
4
5
6
7
8
9
10
11
12
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringApplicationContextInitializer.class)
public class SpringTest {

@Autowired
private UserService userService;

@Test
public void test(){
userService.printUserDao();
}
}

我们发现UseService就是我们的代理对象,并且使用的是JDK的动态代理,JDK动态代理中的h就是动态代理的InvocationHandler。

JdkDynamicAopProxy

继承关系

我们发现JdkDynamicAopProxy继承了InvocationHandler,就是jdk的动态代理,我们主要就是看里面的invok方法

invok

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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/**
* Implementation of {@code InvocationHandler.invoke}.
* <p>Callers will see exactly the exception thrown by the target,
* unless a hook method throws an exception.
* InvocationHandler 的 INVOK方法 AOP调用的入口方法
*/
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;

// 1.advised就是proxyFactory,而targetSource持有被代理对象的引用
//从代理工厂中拿到TargetSource对象,该对象包装了被代理实例bean
TargetSource targetSource = this.advised.targetSource;
Object target = null;

try {
//被代理对象的equals方法和hashCode方法是不能被代理的,不会走切面
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
// 目标不实现equals(Object)方法本身。
return equals(args[0]);
} else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
} else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
// 只有getDecoratedClass()声明 - > dispatch到代理配置。
return AopProxyUtils.ultimateTargetClass(this.advised);
} else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
// ProxyConfig上的服务调用与代理配置...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}

Object retVal;

// 有时候目标对象内部的自我调用将无法实施切面中的增强则需要通过此属性暴露代理
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}

// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
// 2.拿到我们被代理的对象实例
//这个target就是被代理实例
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);

// Get the interception chain for this method.
// 3.获取拦截器链:例如使用@Around注解时会找到AspectJAroundAdvice,还有ExposeInvocationInterceptor
//从代理工厂中拿过滤器链 Object是一个MethodInterceptor类型的对象,其实就是一个advice对象
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
// 4.检查我们是否有任何拦截器(advice)。 如果没有,直接反射调用目标,并避免创建MethodInvocation。
//如果该方法没有执行链,则说明这个方法不需要被拦截,则直接反射调用
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 5.不存在拦截器链,则直接进行反射调用
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} else {
// 6.如果存在拦截器,则创建一个ReflectiveMethodInvocation:代理对象、被代理对象、方法、参数、
// 被代理对象的Class、拦截器链作为参数创建ReflectiveMethodInvocation
// We need to create a method invocation...
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
// 7.触发ReflectiveMethodInvocation的执行方法
retVal = invocation.proceed();
}

// Massage return value if necessary.
// 8.必要时转换返回值
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
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);
}
}
}

3.获取拦截器链:使用 @Around 注解时会找到 AspectJAroundAdvice,还有 ExposeInvocationInterceptor,其中 ExposeInvocationInterceptor 在前,AspectJAroundAdvice 在后。

6.如果存在拦截器,则创建一个 ReflectiveMethodInvocation,代理对象、被代理对象、方法、参数、被代理对象的 Class、拦截器链作为参数。这边 ReflectiveMethodInvocation 已经持有了被代理对象、方法、参数,后续就可以直接使用反射来调用被代理的方法了,见代码块1。

7.触发 ReflectiveMethodInvocation 的执行方法,见代码块ReflectiveMethodInvocation 构造函数。

getInterceptorsAndDynamicInterceptionAdvice

获取动态代理的拦截器链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* Determine a list of {@link org.aopalliance.intercept.MethodInterceptor} objects
* for the given method, based on this configuration.
* <p>
* 获取动态代理的拦截器链
*
*/
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
//创建cacheKey
MethodCacheKey cacheKey = new MethodCacheKey(method);
//从缓存中获取拦截器链
List<Object> cached = this.methodCache.get(cacheKey);
//如果缓存中不存在
if (cached == null) {
//获取过滤器链
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
//加入缓存
this.methodCache.put(cacheKey, cached);
}
//返回拦截器链
return cached;
}
getInterceptorsAndDynamicInterceptionAdvice

获取动态代理的切面的拦截器链

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
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {

// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
//从代理工厂中获得该被代理类的所有切面advisor,config就是代理工厂对象
Advisor[] advisors = config.getAdvisors();
//创建拦截器链
List<Object> interceptorList = new ArrayList<>(advisors.length);
//获取真实被代理的class
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
//遍历所有的切面
for (Advisor advisor : advisors) {
//大部分走这里
//如果是实现了PointcutAdvisor接口
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
//强转成PointcutAdvisor
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
//如果切面的pointCut和被代理对象是匹配的,说明是切面要拦截的对象
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
//获取切点表达式的MethodMatcher
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
//如果是引介
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
} else {
//接下来判断方法是否是切面pointcut需要拦截的方法
match = mm.matches(method, actualClass);
}
//如果类和方法都匹配
if (match) {
//获取到切面advisor中的advice,并且包装成MethodInterceptor类型的对象
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) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
} else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
//如果是引介切面
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
} else {
//将切面转换成Interceptor
Interceptor[] interceptors = registry.getInterceptors(advisor);
//将转换后的切面加入到拦截器链
interceptorList.addAll(Arrays.asList(interceptors));
}
}
//返回拦截器链
return interceptorList;
}
getInterceptors

主要将实现不同接口的切面转换成统一的MethodInterceptor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
//获取切面
Advice advice = advisor.getAdvice();
//如果是MethodInterceptor类型的,如:AspectJAroundAdvice
//AspectJAfterAdvice
//AspectJAfterThrowingAdvice
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
//处理 AspectJMethodBeforeAdvice AspectJAfterReturningAdvice
//使用装饰器模式进行装饰,转换成统一的MethodInterceptor
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}

ReflectiveMethodInvocation

该类是反射方法调用的核心方法

构造方法

1
2
3
4
5
6
7
8
9
10
11
12
protected ReflectiveMethodInvocation(
Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,
@Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {

this.proxy = proxy;
this.target = target;
this.targetClass = targetClass;
this.method = BridgeMethodResolver.findBridgedMethod(method);
this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
}

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
@Override
@Nullable
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
// 1.如果所有拦截器都执行完毕(index是从-1开始,所以跟size - 1比较),则直接使用反射调用连接点(也就是我们原本的方法)
//如果执行链中的advice全部执行完,则直接调用joinPoint方法,就是被代理方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}

// 2.每次调用时,将索引的值递增,并通过索引拿到要执行的拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 3.判断拦截器是否为InterceptorAndDynamicMethodMatcher类型(动态方法匹配拦截器)
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
// 进行动态匹配。在此评估动态方法匹配器:静态部件已经过评估并且发现匹配。
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.
// Skip this interceptor and invoke the next in the chain.
// 动态匹配失败。跳过此拦截器并调用链中的下一个。
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
// 4.只是一个普通的拦截器,则触发拦截器链责任链的调用,并且参数为ReflectiveMethodInvocation本身
//调用MethodInterceptor中的invoke方法
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}

invokeJoinpoint

1
2
3
4
5
@Nullable
protected Object invokeJoinpoint() throws Throwable {
// 反射执行连接点,也就是原方法,target为被代理的对象实例、method为执行的方法、arguments为方法参数
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
invokeJoinpointUsingReflection
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
/**
* Invoke the given target via reflection, as part of an AOP method invocation.
* 使用反射调用切点
*
*/
@Nullable
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
throws Throwable {

// Use reflection to invoke the method.
try {
// 使用反射调用方法
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
} catch (InvocationTargetException ex) {
// Invoked method threw a checked exception.
// We must rethrow it. The client won't see the interceptor.
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);
}
}

ExposeInvocationInterceptor

暴漏拦截器的入口,其他拦截器都是从这里开始的

继承关系

invoke

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = invocation.get();
// 1.设置为当前的MethodInvocation
invocation.set(mi);
try {
// 2.继续进入链中的下一个拦截器。
return mi.proceed();
}
finally {
// 3.执行结束设置回原来的MethodInvocation
invocation.set(oldInvocation);
}
}

继续进入链中的下一个拦截器,该方法会回到代码块ReflectiveMethodInvocation 构造函数,从而拿到下一个拦截器,并触发其 invoke 方法,在本例中也就是:AspectJAroundAdvice#invoke,见代码块5。

AspectJAroundAdvice

环绕通知的拦截器

继承关系

invoke

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 1.这边的mi就是我们的ReflectiveMethodInvocation,
// ReflectiveMethodInvocation实现了ProxyMethodInvocation接口,所以这边肯定通过校验
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
// 2.将mi直接强转成ProxyMethodInvocation,mi持有代理类实例proxy、被代理类实例target、被代理的方法method等
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
// 3.将pmi封装层MethodInvocationProceedingJoinPoint(直接持有入参mi,也就是ReflectiveMethodInvocation的引用)
ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
// 4.拿到pointcut的表达式
JoinPointMatch jpm = getJoinPointMatch(pmi);
// 5.调用增强方法
return invokeAdviceMethod(pjp, jpm, null, null);
}
invokeAdviceMethod
1
2
3
4
5
6
protected Object invokeAdviceMethod(JoinPoint jp, @Nullable JoinPointMatch jpMatch,
@Nullable Object returnValue, @Nullable Throwable t) throws Throwable {
// 1.argBinding:获取方法执行连接点处的参数
// 2.invokeAdviceMethodWithGivenArgs:使用给定的参数调用增强方法
return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t));
}
argBinding

参数绑定

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
protected Object[] argBinding(JoinPoint jp, @Nullable JoinPointMatch jpMatch,
@Nullable Object returnValue, @Nullable Throwable ex) {

calculateArgumentBindings();

// AMC start
Object[] adviceInvocationArgs = new Object[this.parameterTypes.length];
int numBound = 0;

if (this.joinPointArgumentIndex != -1) {
// 1.如果存在连接点参数,则将jp添加到调用参数
// 当使用@Around时就有参数;使用@Before、@After时就没有参数
adviceInvocationArgs[this.joinPointArgumentIndex] = jp;
numBound++;
}
else if (this.joinPointStaticPartArgumentIndex != -1) {
adviceInvocationArgs[this.joinPointStaticPartArgumentIndex] = jp.getStaticPart();
numBound++;
}

if (!CollectionUtils.isEmpty(this.argumentBindings)) {
// binding from pointcut match
// 2.使用pointcut匹配绑定
if (jpMatch != null) {
PointcutParameter[] parameterBindings = jpMatch.getParameterBindings();
for (PointcutParameter parameter : parameterBindings) {
String name = parameter.getName();
Integer index = this.argumentBindings.get(name);
adviceInvocationArgs[index] = parameter.getBinding();
numBound++;
}
}
// binding from returning clause
// 3.用于绑定@AfterReturing中的returning参数
if (this.returningName != null) {
Integer index = this.argumentBindings.get(this.returningName);
adviceInvocationArgs[index] = returnValue;
numBound++;
}
// binding from thrown exception
// 4.用于绑定@AfterThrowing中的throwing参数
if (this.throwingName != null) {
Integer index = this.argumentBindings.get(this.throwingName);
adviceInvocationArgs[index] = ex;
numBound++;
}
}

if (numBound != this.parameterTypes.length) {
throw new IllegalStateException("Required to bind " + this.parameterTypes.length +
" arguments, but only bound " + numBound + " (JoinPointMatch " +
(jpMatch == null ? "was NOT" : "WAS") + " bound in invocation)");
}

return adviceInvocationArgs;
}

​ 如果存在连接点参数,则将 jp 添加到增强方法的参数数组,对于 @Around 来说,这边的 jp 就是代码块invoke中的入参 mi,也就是我们之前创建的 ReflectiveMethodInvocation 对象。所以,当使用 @Around 时,这边返回的增强方法的参数数组持有的是 ReflectiveMethodInvocation 对象。

invokeAdviceMethodWithGivenArgs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
Object[] actualArgs = args;
// 1.如果增强方法没有参数,则将actualArgs赋值为null
if (this.aspectJAdviceMethod.getParameterCount() == 0) {
actualArgs = null;
}
try {
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
// TODO AopUtils.invokeJoinpointUsingReflection
// 2.反射执行增强方法
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();
}
}

​ 反射执行增强方法,对于本文给出的例子,这边会直接走到 LogInterceptor 中被 @Around 修饰的 around(ProceedingJoinPoint pjp) 方法,该方法会执行一些增强逻辑,最终执行 “Object result = pjp.proceed()”。

1
2
3
4
5
6
7
@Around("pointCut()")
public void around(ProceedingJoinPoint point) throws Throwable {
System.out.println("环绕通知");
//继续执行后面的切面拦截器
point.proceed();
System.out.println("环绕通知");
}

​ 通过代码块invokeAdviceMethod和代码块argBinding我们知道,这边的 pjp 就是我们之前创建的 ReflectiveMethodInvocation 对象,所以这边会再次调用 ReflectiveMethodInvocation 对象的 process() 方法,也就是回到代码块proceed。此时我们的拦截器都已经执行完毕,因此会走到 invokeJoinpoint() 方法,通过反射执行我们被代理的方法,也就是 getName(String name) 方法。

至此,AOP 的一次调用流程就全部走通了。

AspectJAfterAdvice

后置通知的拦截器

继承关系

invoke

1
2
3
4
5
6
7
8
9
10
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
//继续执行后面的拦截去
return mi.proceed();
} finally {
//在finally中调用增强方法
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}

invokeAdviceMethod方法可以参考环绕通知的是一样的

MethodBeforeAdviceInterceptor

前置通知的包装类,包装了对AspectJMethodBeforeAdvice前置通知的装饰,装饰器模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {

private final MethodBeforeAdvice advice;


/**
* Create a new MethodBeforeAdviceInterceptor for the given advice.
* @param advice the MethodBeforeAdvice to wrap
*/
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}


@Override
public Object invoke(MethodInvocation mi) throws Throwable {
//调用AspectJMethodBeforeAdvice前置通知的增强方法
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
//继续执行后面的切面
return mi.proceed();
}
}

AspectJMethodBeforeAdvice

调用before会调用到AspectJMethodBeforeAdvice的before的方法

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

public AspectJMethodBeforeAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {

super(aspectJBeforeAdviceMethod, pointcut, aif);
}


@Override
public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
//调用切面的增强方法
invokeAdviceMethod(getJoinPointMatch(), null, null);
}

@Override
public boolean isBeforeAdvice() {
return true;
}

@Override
public boolean isAfterAdvice() {
return false;
}

}

到此位置基本所有涉及到的拦截器都介绍了,其他的都是类似。

总结

AspectJ 方式的 AOP 内容到此就介绍完毕了,核心流程如下。

  1. 解析 AOP 的注解,并注册对应的内部管理的自动代理创建者的 bean,对于本次介绍是:AnnotationAwareAspectJAutoProxyCreator,其他的还有 InfrastructureAdvisorAutoProxyCreator 和 AspectJAwareAdvisorAutoProxyCreator。

  2. 当我们的 bean 初始化完毕后,会触发所有 BeanPostProcessor 的 postProcessAfterInitialization 方法,此时就会调用我们的 AnnotationAwareAspectJAutoProxyCreator 的 postProcessAfterInitialization 方法。该方法会查找我们定义的切面类(使用 @Aspect 注解),创建切面类中定义的增强器(使用 @Before、@After、@Around 等注解),并根据 @Pointcut 的 execution 表达式筛选出适用于当前遍历的 bean 的增强器, 将适用于当前遍历的 bean 的增强器作为参数之一创建对应的 AOP 代理。

  3. 当调用到被 AOP 代理的方法时,会走到对应的代理方法:JdkDynamicAopProxy#invoke 或 DynamicAdvisedInterceptor#intercept,该方法会创建 ReflectiveMethodInvocation,通过责任链的方式来执行所有的增强器和被代理的方法。

评论