spring aop 5.0.8
spring aop/ioc
spring ioc依赖注入对象为 原生 对象,经过spring aop切面对象为 代理 对象
aop 执行过程
cglib代理与jdk代理执行逻辑相同,执行类同为ReflectiveMethodInvocation
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
// 初始化当前执行的拦截器下标
private int currentInterceptorIndex = -1;
@Override
@Nullable
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 顺序遍历执行集合,形成链式调用
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// 评估动态方法匹配器这里:静态部分将已经被评估,并找到匹配。
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// 跳过这个拦截器并调用链中的下一个
return proceed();
}
}
else {
// 它是一个拦截器,所以我们只是调用它:在构造这个对象之前,切入点将被静态地求值。
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
}
在aop中形成执行链,按顺序执行,但实际执行的优先级如下图:
- 在执行
@Around
方法时执行的ProceedingJoinPoint.proceed()
方法,先执行@Before
方法 - 在
@Before
方法执行完成后,最先执行完成的是被代理的方法 - 被代理的方法执行完成之后将
@Around
方法剩余部分执行完成,并按图中3的方向顺序将剩余切面拦截器执行完成
正常aop执行过程
- around before
- before
- around after
- after
- after returning
在方法正常执行结束无异常时,@AfterThrowing
方法并未捕获到异常,所以不再执行after throwing
@SuppressWarnings("serial")
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
implements MethodInterceptor, AfterAdvice, Serializable {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
if (shouldInvokeOnThrowing(ex)) {
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}
}
aop异常拦截
- around before
- before
- after
- after throwing
在抛出异常时@Around
方法执行结束,不会再执行around after
部分的代码
而@AfterReturning
的拦截如同@Around
方法,未捕获异常,所以@AfterReturning
方法执行结束,一样的不会再执行after returning
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
}