spring aop初解

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中形成执行链,按顺序执行,但实际执行的优先级如下图:

  1. 在执行@Around方法时执行的ProceedingJoinPoint.proceed()方法,先执行@Before方法
  2. @Before方法执行完成后,最先执行完成的是被代理的方法
  3. 被代理的方法执行完成之后将@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;
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值