从这里我们需要注意到的是:ProxyMethodInvocation
(ReflectiveMethodInvocation
)是代理执行的入口。然后内部会把所有的 增强器 都拿出来 递归执行
(比如前置通知,就在目标方法之前执行) **这就实现了指定次序的链式调用**
CglibMethodInvocation
它是继承自ReflectiveMethodInvocation
,是CglibAopProxy
自己使用的执行器。
private static class CglibMethodInvocation extends ReflectiveMethodInvocation { private final MethodProxy methodProxy; private final boolean publicMethod; public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method, Object[] arguments, @Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) { // 调用父类的构造 完成基本参数得初始化 super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers); // 自己的个性化参数: // 这个参数是子类多传的,表示:它是CGLIb拦截的时候的类MethodProxy //MethodProxy为生成的代理类对方法的代理引用。cglib生成用来代替Method对象的一个对象,使用MethodProxy比调用JDK自身的Method直接执行方法效率会有提升 // 它有两个重要的方法:invoke和invokeSuper this.methodProxy = methodProxy; // 方法是否是public的 对应下面的invoke方法的处理 见下面 this.publicMethod = Modifier.isPublic(method.getModifiers()); } @Override protected Object invokeJoinpoint() throws Throwable { // 如果是public的方法,调用methodProxy去执行目标方法 // 否则直接执行method即可 if (this.publicMethod) { // 此处务必注意的是,传入的是target,而不能是proxy,否则进入死循环 return this.methodProxy.invoke(this.target, this.arguments); } else { return super.invokeJoinpoint(); } } }
org.aopalliance.intercept.MethodInterceptor
需要说明的cglib包里也存在一个MethodInterceptor,它的主要作用是CGLIB内部使用,一般是和Enhancer一起来使用而创建一个动态代理对象。
而本处我们讲到的 org.aopalliance.intercept.MethodInterceptor,那些@AspectJ定义的通知们(增强器们),或者是自己实现的MethodBeforeAdvice、AfterReturningAdvice…(总是都是org.aopalliance.aop.Advice一个通知器),最终都会被包装成一个org.aopalliance.intercept.MethodInterceptor,最终交给MethodInvocation(其子类ReflectiveMethodInvocation)去执行,它会把你所有的增强器都给执行了,这就是我们面向切面编程的核心思路过程。
这里面其实有两个标记接口(没有任何方法):
顶层接口:Advice 中文意思:建议,忠告。 实现通知的方式可议是任何方式,比如Interceptors拦截器得方式
中间层接口:Interceptor 继承自Advice接口。它就是以拦截器方式去实现通知的效果
此处需要说明的是,Interceptor得子接口有两个:MethodInterceptor和ConstructorInterceptor,但是ConstructorInterceptor连Spring都没有提供实现类,因此本文不会讲述本接口。
// 从名字里都能看出来,它是通过拦截方法的执行来实现通知得效果的~~~~ @FunctionalInterface public interface MethodInterceptor extends Interceptor { // 可议在此方法里 在方法执行之前、之后做对应的处理。 // 需要执行的时候,调用invocation.proceed()方法即可 Object invoke(MethodInvocation invocation) throws Throwable; }
Spring给我们提供的MethodInterceptor实现非常非常的多:
有很多我们非常熟悉的面孔。下面就抽出几个,简单的看看实现代码:
关于AspectJ切面相关的增强器
一共5个对应着AspectJ提供的那五个注解。每个注解都是一个最终被包装好的Advice(其实是个AspectJAfterAdvice) 此处知道就可,暂时此处不做详细介绍~~
MethodBeforeAdviceInterceptor
这个源代码很简单,就是一层代理。把MethodBeforeAdvice
包装成了一个MethodInterceptor
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable { private MethodBeforeAdvice advice; public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } @Override public Object invoke(MethodInvocation mi) throws Throwable { // 在目标方法执行之前,先执行advice得before方法~~~ this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); // 注意此处继续调用了 mi.proceed()。相当于去执行下一个增强器。类似于递归执行了,这样就行程了一个链式得调用执行 return mi.proceed(); } }