AOP责任链源码解析

1. 实现了MethodInterceptor接口的3个通知类

1.1 后置通知
public class AspectJAfterAdvice extends AbstractAspectJAdvice
		implements MethodInterceptor, AfterAdvice, Serializable {
     //...
	//它的业务逻辑就是执行下一个通知,最终调用下标记的方法
	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
			// 执行下一个通知/拦截器
			return mi.proceed();
		}
		finally {
			// 后置通知的方法总是会被执行,原因就在这finally
			invokeAdviceMethod(getJoinPointMatch(), null, null);
		}
	}
//...
}
1.2 后置异常通知
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
		implements MethodInterceptor, AfterAdvice, Serializable {
    //...
    	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
			// 执行下一个通知/拦截器  methodInvocation
			// 可能是回到最开始的地方,
			return mi.proceed();
		}
		catch (Throwable ex) {
			// 抛出异常,异常的时候,才去执行异常的通知
			if (shouldInvokeOnThrowing(ex)) {
				// 执行异常通知
				invokeAdviceMethod(getJoinPointMatch(), null, ex);
			}
			throw ex;
		}
	}
    //....    
}
1.3 环绕通知
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);
		}
		ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
		ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
		JoinPointMatch jpm = getJoinPointMatch(pmi);
		//开始执行具体的逻辑。
		// 重点! 执行前置的逻辑,然后在标记的方法里面,继续执行调用链
		return invokeAdviceMethod(pjp, jpm, null, null);
	}
    //....
}

2. 没有实现了MethodInterceptor接口

借助适配器实现

2.1 后置响应通知
class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {

	@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof AfterReturningAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();
		return new AfterReturningAdviceInterceptor(advice);
	}
}



public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {

	private final AfterReturningAdvice advice;
    //............
	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		// 执行下一个通知/拦截器,执行完之后,再执行返回通知
		Object retVal = mi.proceed();
		// 返回通知方法
		this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
		return retVal;
	}

}


public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implements AfterReturningAdvice, AfterAdvice, Serializable {
    //......
    	@Override
	public void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable {
		if (shouldInvokeOnReturnValueOf(method, returnValue)) {
            //执行通知的方法
			invokeAdviceMethod(getJoinPointMatch(), returnValue, null);
		}
	}
   //....
}

protected Object invokeAdviceMethod(...)throws Throwable {
		return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex));
	}



protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
		Object[] actualArgs = args;
		// 判断通知方法是否有参数
		if (this.aspectJAdviceMethod.getParameterCount() == 0) {
			actualArgs = null;
		}
		try {
			ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
			// TODO AopUtils.invokeJoinpointUsingReflection
			// 反射调用通知方法
			// this.aspectInstanceFactory.getAspectInstance()获取的是切面的实例 。
			// 1.如果是around过来的。 这里是调到around标记的方法 。通过反射执行到原方法。before 的前置
			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();
		}
	}


2.2 前置通知处理器
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
	@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof MethodBeforeAdvice);
	}
	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
		return new MethodBeforeAdviceInterceptor(advice);
	}

}

//注意实现了MethodInterceptor接口
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
    
	private final MethodBeforeAdvice advice;
	//.....

	// 这个invoke方法是拦截器的回调方法,会在代理对应的方法被调用时触发回调
	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		// 执行前置通知的方法(代码中写的前置执行逻辑)
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
		// 执行下一个通知/拦截器。
		// 直到所有的通知都走完了,走到目标方法,然后开始返回
		return mi.proceed();
	}

}


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);
	}
    
    
}

3. 调用链

3.1 JDK

JdkDynamicAopProxy.java

开始链式调用,也是借助ReflectiveMethodInvocation类来实现的。后面的链式调用中,mi.proceed()就回到了ReflectiveMethodInvocation的proceed方法中

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {

invoke(){
//.....
	// 从Advised中根据方法名和目标类获取AOP拦截器执行链
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

MethodInvocation invocation =  new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);

// 将拦截器封装在ReflectiveMethodInvocation,以便于使用其proceed进行处理 。开始调用责任链了
				MethodInvocation invocation =
						new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// Proceed to the joinpoint through the interceptor chain.
				// 执行拦截器链
				retVal = invocation.proceed();
				
}				
3.1 Cglib

内部类CglibAopProxy.java#DynamicAdvisedInterceptor.java

private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable{
intercept(){
//.....
// 从advised中获取配置好的AOP通知
				List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
	//开始链式调用			
    retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();        
	}
}				

借助CglibMethodInvocation来实现链式调用的,该类的父类是ReflectiveMethodInvocation,通过proceed方法,继而调用到ReflectiveMethodInvocation的proceed方法。

private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
//.....
public Object proceed() throws Throwable {
			try {
				return super.proceed();
			}
}

}

上面两种代理的链式调用,用到的核心重点类ReflectiveMethodInvocation

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
    
    public Object proceed() throws Throwable {
		// We start with an index of -1 and increment early.
		// 从索引为-1的拦截器开始调用,并按序递增,如果拦截器链中的拦截器迭代调用完毕,开始调用target的函数,这个函数是通过反射机制完成的
		// 具体实现在AopUtils.invokeJoinpointUsingReflection方法中
		// 实际执行的方法(被代理类的方法)
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

		// 获取下一个要执行的拦截器,沿着定义好的interceptorOrInterceptionAdvice链进行处理
		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			// Evaluate dynamic method matcher here: static part will already have
			// been evaluated and found to match.
			// 这里对拦截器进行动态匹配的判断,这里是对pointcut触发进行匹配的地方,如果和定义的pointcut匹配,那么这个advice将会得到执行
			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.
				// 如果不匹配,那么proceed会被递归调用,知道所有的拦截器都被运行过位置
				return proceed();
			}
		}
		else {
			// 普通拦截器,直接调用拦截器,将this作为参数传递以保证当前实例中调用链的执行。
			// 这个this很灵魂,是整个责任链的核心,是cglibAopProxy ,是责任链的起点
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}
    
    
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0uoU4W8P-1681190913197)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230410134118468.png)]

总结

ReflectiveMethodInvocation是连接起责任链的那条线,CglibMethodInvocation这个子类是cglib的哪条线,不过核心逻辑还是ReflectiveMethodInvocation实现的。

Before和Around的前半部分;After和AfterRturning 的顺序经过排序之后,不通版本,不通编写位置,执行前后是不一样的,具体看sortAdvisors()。 通知的实现,在各个通知的代码中,比如 AspectJAfterThrowingAdvice 异常的执行逻辑,在catch中执行invokeAdviceMethod() ,其它类似

你可能感兴趣的:(Spring源码解析,spring)