原文:SpringAOP联盟(5)-MethodInvocation(拦截器的调用) - 简书 (jianshu.com)
在上文中,代理对象创建后,最终的拦截工作都是交给了MethodInvocation。JDK交给了ReflectiveMethodInvocation
,而CGLIB交给CglibMethodInvocation
。
此处所说的MethodInvocation
是AOP联盟包下的,也就是org.aopalliance.intercept.MethodInvocation
。
此接口会继承Joinpoint
接口,注意不要和org.aspectj.lang.JoinPoint
搞混。
org.aspectj.lang.JoinPoint
:该对象封装了SpringAop中切面方法信息,在切面方法添加JoinPoint
参数,可以很方便的获取更多信息。(一般用于@Aspect
标注的切面方法入参)。
org.aopalliance.intercept.Joinpoint
是AOP联盟中的类,关系如下图所示:
//此接口表示运行时的连接点(AOP术语)
public interface Joinpoint {
//执行此拦截点,并进入下一个连接点
Object proceed() throws Throwable;
//保存当前连接点静态对象,这里一般指的是target
Object getThis();
//返回此静态连接点,一般就为当前的Method
AccessibleObject getStaticPart();
}
public interface Invocation extends Joinpoint {
//获取参数,例如方法的参数
Object[] getArguments();
}
// 方法调用时,对这部分进行描述
public interface MethodInvocation extends Invocation {
// 返回正在被调用得方法,返回的是当前Method对象。
// 此时,效果同父类的AccessibleObject getStaticPart() 这个方法
Method getMethod();
}
MethodInvocation
作为aopalliance
里提供的最底层的接口。Spring也提供了相关的实现。
Spring也提供了一个接口
proxyMethodInvoation
来进行扩展使用。
public interface ProxyMethodInvocation extends MethodInvocation {
//返回代理对象
Object getProxy();
//clone一个,使用的是Object的clone方法
MethodInvocation invocableClone();
MethodInvocation invocableClone(Object... arguments);
//设置参数 增强器、通知执行的时候可能会使用到
void setArguments(Object... arguments);
//添加一些kv,但这些kv并不会用于AOP框架,而是保存起来给特殊的拦截器使用
void setUserAttribute(String key, @Nullable Object value);
@Nullable
Object getUserAttribute(String key);
}
1. ReflectiveMethodInvocation
Spring提供的实现类:org.springframework.aop.framework.ReflectiveMethodInvocation
该类作为实现类,会实现包含父父类所有的抽象方法。
他也是JdkDynamicAopProxy
最终要new出来的类。
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
protected final Object proxy; // 代理对象
@Nullable
protected final Object target; // 目标对象
protected final Method method; // 被拦截的方法
protected Object[] arguments = new Object[0];
@Nullable
private final Class<?> targetClass;
@Nullable
private Map userAttributes;
protected final List<?> interceptorsAndDynamicMethodMatchers;
// currentInterceptorIndex初始值为 -1(拦截链初始值为-1)
private int currentInterceptorIndex = -1;
//Spring内部使用的类
protected ReflectiveMethodInvocation(
Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,
@Nullable Class<?> targetClass, List
2. CglibMethodInvocation
它是
ReflectiveMethodInvocation
的唯一子类,是Cglib自己使用的执行器。你可以将其看做为工厂模式,它会实现一些Cglib特有的方法。
并且
CglibMethodInvocation
是
CglibAopProxy
的静态内部类。
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
@Nullable
private final MethodProxy methodProxy;
public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
Object[] arguments, @Nullable Class<?> targetClass,
List
那些
@AspectJ
定义的通知(增强器),或者自己实现的
MethodBeforeAdvice、AfterReturningAdvice...
最终都会被包装为一个
org.aopalliance.intercept.MethodInterceptor
,交由MethodInvocation(其子类是
ReflectiveMethodInvocation
)去执行,它会将该方法上的拦截器链缓存,并递归调用执行。
推荐阅读
https://blog.csdn.net/f641385712/article/details/88975543