看这一篇前最好先看上一篇,具有连续性:https://blog.csdn.net/nandao158/article/details/105873916
这篇解析代理实例调用的核心方法:
1、接着上篇:
//如果该方法没有执行链,则说明这个方法不需要被拦截,则直接反射调用
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
//如果该方法有advice执行链,需要被拦截、点击进入 核心点 -->
retVal = invocation.proceed();
}
2、ctrl+t 进入 ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable 的 proceed 方法:
@Override
@Nullable
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
//这里维护了执行链advice 数组和数组索引
//如果执行链中的advice全部执行完,则直接调用joinPoint方法,就是被代理方法,完成功能增强
//当判断当前索引==执行链数组大小时就会调用到被代理方法,完成 aop 增强过程,核心点
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();//遍历完成后最好点击进入-->
}
//循环计数,直到循环结束(执行链数组达到最大值)
/**
这时候索引又会+1,然后从链中后调下一个 advice, 调用完后再 mi.proceed()又会接着循环调用
,就这样形成了一个链式调用过程。直到数组链中全部调用 完后会调用到具体的 上面的 joinPoint 方法,
*/
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.
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);//这个方法里面也是循环调 proceed 方法
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();//火炬传递,循环调用,直到 advice全部执行完
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
//调用MethodInterceptor中的invoke方法 ,这个方法里面也是循环调 proceed 方法,进入举例看一下-->
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
3、进入接口方法后ctrl+t 来到: AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();//此处又去循环advice
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
4、现在开始正式 对目标方法功能增强:点击 invokeJoinpoint()
@Nullable
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);//点击--》
}
5、来到: AopUtils 工具类 ,
@Nullable
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 (InvocationTargetException ex) {
// Invoked method threw a checked exception.
// We must rethrow it. The client won't see the interceptor.
throw ex.getTargetException();
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
method + "] on target [" + target + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopInvocationException("Could not access method [" + method + "]", ex);
}
}
6、到这里springAOP 代理类的创建和调用(功能增强),已经完成,大家可以结合源码和注释多看几遍,加深理解,有不明白的地方可以留言!!!