AOP的拦截链
之前我们看到代理对象的目标方法长这个样子,这时就出现一个问题,如果是这种实现,那么像@After和@AfterThrowing这样的Advice是如何判断定位到执行目标方法结束的时机?
还是拿之前的示例来看
首先是目标方法具有Advisor,然后进入MethodInvocation处理
ReflectiveMethodInvocation处理
然后进入ReflectiveMethodInvocation的处理,这里有一个currentInterceptorIndex的判断。很重要的一步,之后会回头说明。
执行MethodBeforeAdviceInterceptor#invoke
从MethodBeforeAdviceInterceptor回到ReflectiveMethodInvocation——拦截链的调用
这里的mi就是CglibMethodInvocation,然后又通过super返回到ReflectiveMethodInvocation的处理
这就是Advice调用链的实现。既然是调用链就有停止的时候,就需要有条件判断,这就回到我们之前所说的判断
这里的判断加上后续的currentInterceptorIndex的不断增加,构成的逻辑就是
if (i = list.size() -1) {
结束Advice遍历;
执行目标方法;
};
i++;
每次执行一个Advice的invoke方法,就会实现i++;
// 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);
@After的特殊实现
我们回到After相关Advice的invoke方法AspectJAfterAdvice#invoke
可以看到它的实现和普通的Advice实现不同,将自己置于ReflectiveMethodInvocation实现之后(ReflectiveMethodInvocation最后做的事就是调用目标方法),现在应该猜到了为什么@After能够知道目标方法执行之后的时机,可以理解为@After实现了延后执行(之后就会发现延后到目标方法执行完执行)
继续回到ReflectiveMethodInvocation的处理
Advice链执行到头,执行目标方法
这是ReflectiveMethodInvocation执行结束,会跳转到AspectJAfterAdvice#invoke中的finally处理