类图
ReflectiveMethodInvocation
属性
protected final Object proxy;
@Nullable
protected final Object target;
protected final Method method;
protected Object[] arguments = new Object[0];
@Nullable
private final Class<?> targetClass;
/**
* Lazily initialized map of user-specific attributes for this invocation.
*/
@Nullable
private Map<String, Object> userAttributes;
/**
* List of MethodInterceptor and InterceptorAndDynamicMethodMatcher
* that need dynamic checks.
*/
protected final List<?> interceptorsAndDynamicMethodMatchers;
/**
* Index from 0 of the current interceptor we're invoking.
* -1 until we invoke: then the current interceptor.
*/
private int currentInterceptorIndex = -1;
构造方法
protected ReflectiveMethodInvocation(
Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,
@Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
this.proxy = proxy; // 代理类
this.target = target; // 目标对象
this.targetClass = targetClass; //目标类
this.method = BridgeMethodResolver.findBridgedMethod(method); // 目标方法
this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments); // 目标方法参数
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers; // List of MethodInterceptor
}
proceed
执行MethodInterceptor.proceed()的时候(see 下面MethodBeforeAdviceInterceptor的invoke方法),会依次处理interceptorsAndDynamicMethodMatchers中的MethodInterceptor,
这里interceptorsAndDynamicMethodMatchers有2种类型,一种是InterceptorAndDynamicMethodMatcher,这个类持有
MethodInterceptor,另外就是直接实现了MethodInterceptor接口的类,proceed其实使用了责任链模式
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early. 从-1开始 第一次调用是-1
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint(); // 全部执行后,会执行invokeJoinpoint
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); // ++this.currentInterceptorIndex 由于默认是-1,这里从0开始的
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // 处理InterceptorAndDynamicMethodMatcher
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
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 { //匹配失败,则跳过当前的interceptor,处理下一个
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else { // 处理MethodInterceptor
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
invokeJoinpoint
反射调用目标方法
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
AopUtils
invokeJoinpointUsingReflection其实就是1个反射调用目标方法
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
throws Throwable {
// Use reflection to invoke the method.
try {
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
}
catch (Exception ex) {
}
}
invocableClone
/**
* This implementation returns a shallow copy of this invocation object, 浅拷贝
* including an independent copy of the original arguments array. 包括独立的arguments
* <p>We want a shallow copy in this case: We want to use the same interceptor
* chain and other object references, but we want an independent value for the
* current interceptor index. 拷貝的時候currentInterceptorIndex是相同的,之后就独立了
* @see java.lang.Object#clone()
*/
@Override
public MethodInvocation invocableClone() {
Object[] cloneArguments = this.arguments;
if (this.arguments.length > 0) {
// Build an independent copy of the arguments array.
cloneArguments = new Object[this.arguments.length];
System.arraycopy(this.arguments, 0, cloneArguments, 0, this.arguments.length);
}
return invocableClone(cloneArguments);
}
/**
* This implementation returns a shallow copy of this invocation object,
* using the given arguments array for the clone.
* <p>We want a shallow copy in this case: We want to use the same interceptor
* chain and other object references, but we want an independent value for the
* current interceptor index.
* @see java.lang.Object#clone()
*/
@Override
public MethodInvocation invocableClone(Object... arguments) {
// Force initialization of the user attributes Map,
// for having a shared Map reference in the clone.
if (this.userAttributes == null) {
this.userAttributes = new HashMap<>();
}
// Create the MethodInvocation clone.
try {
ReflectiveMethodInvocation clone = (ReflectiveMethodInvocation) clone();
clone.arguments = arguments; //独立的arguments
return clone;
}
catch (CloneNotSupportedException ex) {
throw new IllegalStateException(
"Should be able to clone object of type [" + getClass() + "]: " + ex);
}
}
MethodBeforeAdviceInterceptor
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
private final MethodBeforeAdvice advice;
/**
* Create a new MethodBeforeAdviceInterceptor for the given advice.
* @param advice the MethodBeforeAdvice to wrap
*/
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
}
CglibAopProxy
CglibMethodInvocation
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<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
// Only use method proxy for public methods not derived from java.lang.Object
this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
methodProxy : null);
}
/**
* Gives a marginal performance improvement versus using reflection to
* invoke the target when invoking public methods.
*/
@Override
protected Object invokeJoinpoint() throws Throwable {
if (this.methodProxy != null) {
return this.methodProxy.invoke(this.target, this.arguments);
}
else {
return super.invokeJoinpoint();
}
}
}