spring AOP 代理实例调用(功能增强)的源码解析(十)

看这一篇前最好先看上一篇,具有连续性: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 代理类的创建和调用(功能增强),已经完成,大家可以结合源码和注释多看几遍,加深理解,有不明白的地方可以留言!!!

猜你喜欢

转载自blog.csdn.net/nandao158/article/details/105874695
今日推荐