Spring 纯注解开发--008--AOP原理--目标方法执行

容器中保存了组件的代理对象(cglib增强后的对象),这个对象包含了详细信息(目标对象,增强器,等等)
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    Object oldProxy = null;
    boolean setProxyContext = false;
    Object target = null;
    TargetSource targetSource = this.advised.getTargetSource();

    Object var16;
    try {
        if(this.advised.exposeProxy) {
            oldProxy = AopContext.setCurrentProxy(proxy);
            setProxyContext = true;
        }

        target = targetSource.getTarget();
        Class<?> targetClass = target != null?target.getClass():null;
        //获取拦截器链  1  2 执行
        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
        Object retVal;
        //如果拦截器链为空。直接返回
        if(chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
            Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);		//3. 方法目标对象的方法
            retVal = methodProxy.invoke(target, argsToUse);
        } else {
        	//4. 创建CglibMethodInvocation,并执行proceed方法,增强方法在此执行
        	//此实例为多例,执行proceed方法时,不会存在多线程问题
            retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();
        }

        retVal = CglibAopProxy.processReturnType(proxy, target, method, retVal);
        var16 = retVal;
    } finally {
        if(target != null && !targetSource.isStatic()) {
            targetSource.releaseTarget(target);
        }

        if(setProxyContext) {
            AopContext.setCurrentProxy(oldProxy);
        }

    }

    return var16;
}
  1. CglibAopProxy.intercept();拦截目标对象的方法
  2. 根据ProxyFactory对象,获取将要执行的目标方法的拦截器链
    List< Object > chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    • List< Object > interceptorList 保存所有的拦截器,长度是增强器的个数。
    • 遍历所有的增强器,转成Interceptor
      MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
      
      //getInterceptors
      public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
          List<MethodInterceptor> interceptors = new ArrayList(3);
          Advice advice = advisor.getAdvice();
          if(advice instanceof MethodInterceptor) {
              interceptors.add((MethodInterceptor)advice);
          }
      
          Iterator var4 = this.adapters.iterator();
      
          while(var4.hasNext()) {
              AdvisorAdapter adapter = (AdvisorAdapter)var4.next();
              if(adapter.supportsAdvice(advice)) {
                  interceptors.add(adapter.getInterceptor(advisor));
              }
          }
      
          if(interceptors.isEmpty()) {
              throw new UnknownAdviceTypeException(advisor.getAdvice());
          } else {
              return (MethodInterceptor[])interceptors.toArray(new MethodInterceptor[0]);
          }
      }
      
    • 将增强器转为List< MethodInterceptor > interceptors,拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)
      • 如果是MethodInterceptor直接加入到集合中
      • 如果不是,使用这些增强器的适配器,转为MethodInterceptor,转换完成,返回MethodInterceptor数组。
  3. 如果没有拦截器链,直接执行目标对象的方法
  4. 如果存在拦截器链,把需要执行的目标对象、目标方法,拦截器链等信息创建一个CglibMethodInvocation,并调用proceed方法
retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();
5. 拦截器链的触发过程
@Nullable
    public Object proceed() throws Throwable {
    	//如果没有拦截器
    	//或者拦截器的最后一个方法时,也执行目标方法,因为currentInterceptorIndex会在下面增加
        if(this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        	//内容实质是,利用反射执行目标方法
            return this.invokeJoinpoint();
        } else {
            Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
            if(interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
                InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
                Class<?> targetClass = this.targetClass != null?this.targetClass:this.method.getDeclaringClass();
                return dm.methodMatcher.matches(this.method, targetClass, this.arguments)?dm.interceptor.invoke(this):this.proceed();
            } else {
                return 
              ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
            }
        }
    }
  1. 如果没有拦截器,直接执行目标方法,或者执行拦截器的索引和拦截器数组-1大小一样
    (指定到了最后一个拦截器)执行目标方法
  2. 链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回之后再来执行。通过拦截器链的机制,保证通知方法和目标方法的执行顺序。在这里插入图片描述
具体细节
  1. 使用责任链模式进行执行,依次执行拦截器链中的方法
  2. 通过索引的不断递增,来执行拦截器链中的所有方法
1 . ExposeInvocationInterceptor
public Object invoke(MethodInvocation mi) throws Throwable {
	//共同方法的开头,加入到线程本地变量中,以免重复创建
       MethodInvocation oldInvocation = (MethodInvocation)invocation.get();
       invocation.set(mi);

       Object var3;
       try {
       	//执行proceed方法,
           var3 = mi.proceed();
       } finally {
           invocation.set(oldInvocation);
       }

       return var3;
   }
   
//执行proceed方法   
currentInterceptorIndex++,执行下一个拦截器的Invoke方法
2. AspectJAfterThrowingAdvice
public Object invoke(MethodInvocation mi) throws Throwable {
     try {
     	 //执行下一个拦截器的方法
         return mi.proceed();
     } catch (Throwable var3) {
         if(this.shouldInvokeOnThrowing(var3)) {
         	//自定义的,当出现异常时,执行自定义的异常处理方法
             this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, var3);
         }
		//会继续抛出
         throw var3;
     }
 }
3. AfterReturningAdviceInterceptor
public Object invoke(MethodInvocation mi) throws Throwable {
	//先执行下一个的拦截器方法
     Object retVal = mi.proceed();
     //返回成功,且没有发生异常时,执行自定义的返回后增强方法
     this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
     return retVal;
 }
 
4. MethodBeforeAdviceInterceptor
public Object invoke(MethodInvocation mi) throws Throwable {
	//在执行下一个拦截器的proceed方法之前,执行自定义的方法执行前的增强方法
     this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
     //执行下一个拦截器的方法
     return mi.proceed();
 }

5. proceed
  • currentInterceptorIndex等于长度减1,所以通过反射来执行目标对象方法,执行完后,递归返回去依次执行 4 3 2 1 中相应的逻辑,最后执行完成。
@Nullable
    public Object proceed() throws Throwable {
     //执行目标对象的方法
     if(this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
         return this.invokeJoinpoint();
     } else {
         Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
         if(interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
             InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
             Class<?> targetClass = this.targetClass != null?this.targetClass:this.method.getDeclaringClass();
             return dm.methodMatcher.matches(this.method, targetClass, this.arguments)?dm.interceptor.invoke(this):this.proceed();
         } else {
             return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
         }
     }
 }
//依次调用之后
@Nullable
 public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args) throws Throwable {
     try {
     	//设置访问权限
         ReflectionUtils.makeAccessible(method);
         //通过反射执行目标对象的方法
         return method.invoke(target, args);
     } catch (InvocationTargetException var4) {
         throw var4.getTargetException();
     } catch (IllegalArgumentException var5) {
         throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" + method + "] on target [" + target + "]", var5);
     } catch (IllegalAccessException var6) {
         throw new AopInvocationException("Could not access method [" + method + "]", var6);
     }
 }
总结
  1. @EnableAspectJAutoProxy 开启Aop功能
  2. @EnableAspectJAutoProxy 会给容器中注册一个AnnotationAwareAspectJAutoProxyCreator
  3. AnnotationAwareAspectJAutoProxyCreator是一个后置处理器
  4. 容器的创建流程
    1. registerBeanPostProcessors()注册后置处理器,会创建AnnotationAwareAspectJAutoProxyCreator对象。
    2. finishBeanFactoryInitialization(),初始化剩下的单实例bean
      1. 创建业务逻辑组件和切面组件
      2. AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
      3. 组件创建完成之后,判断组件是否需要增强
        1. 如果需要,切面的通知方法,包装成增强器,然后给业务逻辑组件创建代理对象(cglib),代理对象中有目标对象,以及增强器。
  5. 执行目标方法
    1. 代理对象执行目标方法
    2. CglibAopProxy.intercept()执行
      1. 先获取拦截器链(增强方法)
      2. 利用拦截器链式机制依次进入每一个拦截器执行
      3. 效果
        1. 正常执行:前置通知–》目标方法–》后置通知–》返回通知
        2. 出现异常:前置通知–》目标方法–》后置通知–》异常通知
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值