程序猿
微录

详解Spring的切面编程【AOP】机制 【3:创建代理】

程序猿微录 发布于: 2020-04-25 12:38 163 0 0 0
首页
文章
专栏
问答
寄语
公告
  • 前往登录

详解Spring的切面编程【AOP】机制 【3:创建代理】

程序猿微录 发布于 2020-04-25 12:38 163 0 0 0
所属文册: Spring AOP 文章标签: AOP

Spring AOP 代理的创建

接着上一步,在找到Bean的增强列表后,该利用这些增强器创建代理,整合出一个最终的代理对象出来,入口:AbstractAutoProxyCreator#createProxy

具体流程

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,  @Nullable Object[] specificInterceptors, TargetSource targetSource) {

   // ConfigurableListableBeanFactory实例则将该BeanDefinition添加一个属性originalTargetClass,指向beanClass
   // 在由BeanFactory实例化其他Bean时候使用的BeanDefinition 就会有该属性
   if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
      AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
   }

   ProxyFactory proxyFactory = new ProxyFactory();
   // 原型模式,复制属性 
   proxyFactory.copyFrom(this);

   // 判断代理方式采用的是使用类还是接口 (默认false即采用接口)
   if (!proxyFactory.isProxyTargetClass()) {
      // BeanDdefinition指定了preserveTargetClass=true则使用类
      if (shouldProxyTargetClass(beanClass, beanName)) {
         proxyFactory.setProxyTargetClass(true);
      }
     // 未指定则尝试从类及其父类的所有接口列表中过滤掉回调接口(Aware、DisposableBean等容器接口)、内部接口(“groovy.lang.GroovyObject”等)
     // 从过滤后接口列表中找到合适代理的接口找不到则仍然使用类进行代理   
      else {
         evaluateProxyInterfaces(beanClass, proxyFactory);
      }
   }
   // 构建增强器链
   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
   proxyFactory.addAdvisors(advisors);
   proxyFactory.setTargetSource(targetSource);
   // 模板方法,扩展代理工厂
   customizeProxyFactory(proxyFactory);


   proxyFactory.setFrozen(this.freezeProxy);
   // 优化,如果是已匹配好的则做个标记,后续不在走匹配流程 
   if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
   }
   // 代理工厂生产代理对象 
   return proxyFactory.getProxy(getProxyClassLoader());
}

上面这个创建流程实质为构建该Bean的代理工厂ProxyFactory的过程。这里使用原型模式构建一个专属的ProxyFactory实例,然后初步判断该Bean的创建方式,JDK(接口)还是CGLIB(类)
判断完成之后,则构建该类的增强器链,这个增强器链来源于之前查找的增强器列表,这里只是后续处理下,处理完毕后,设置ProxyFactory基本属性,这样ProxyFactory基本构建完成。customizeProxyFactory则是暴露给使用者的接口,用于扩展ProxyFactory功能。然后工厂就开始工作了。

处理流程也看下,最终Advisor的没变,但是Advice全部转为 DefaultPointcutAdvisor,需要注意的是这里添加了2种增强:1. 公共拦截器:commonInterceptors 2. 默认适配器(AdvisorAdapter)中的适配的Advisor

protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
   // 获取公共的拦截器
   Advisor[] commonInterceptors = resolveInterceptorNames();
   List<Object> allInterceptors = new ArrayList<>();
   // 公共的排在前 
   if (specificInterceptors != null) {
      allInterceptors.addAll(Arrays.asList(specificInterceptors));
      if (commonInterceptors.length > 0) {
         if (this.applyCommonInterceptorsFirst) {
            allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
         }
         else {
            allInterceptors.addAll(Arrays.asList(commonInterceptors));
         }
      }
   }
  
   Advisor[] advisors = new Advisor[allInterceptors.size()];
   // 使用适配器包装处理下,实际为DefaultAdvisorAdapterRegistry
   for (int i = 0; i < allInterceptors.size(); i++) {
      advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
   }
   return advisors;
}

DefaultAdvisorAdapterRegistry#wrap,注意这里的适配器模式

@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
   // 增强器直接强制转型 
   if (adviceObject instanceof Advisor) {
      return (Advisor) adviceObject;
   }
   // 即不是增强器也不是通知器则不支持,抛出异常 
   if (!(adviceObject instanceof Advice)) {
      throw new UnknownAdviceTypeException(adviceObject);
   }
   Advice advice = (Advice) adviceObject;
   // MethodInterceptor的通知器则转为默认切入点增强器
   if (advice instanceof MethodInterceptor) {
      // So well-known it doesn't even need an adapter.
      return new DefaultPointcutAdvisor(advice);
   }
   // 不是MethodInterceptor,则从默认适配器中找到支持的则转为默认切入点增强器  
   for (AdvisorAdapter adapter : this.adapters) {
      // Check that it is supported.
      if (adapter.supportsAdvice(advice)) {
         return new DefaultPointcutAdvisor(advice);
      }
   }
   // 以上都不支持则抛出异常
   throw new UnknownAdviceTypeException(advice);
}

看下代理创建:DefaultAopProxyFactory#createAopProxy

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
   // 代理开启优化配置或者支持类方式代理或者不直接接口代理 
   if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
      Class<?> targetClass = config.getTargetClass();
      if (targetClass == null) {
         throw new AopConfigException("TargetSource cannot determine target class: " +
               "Either an interface or a target is required for proxy creation.");
      }
      // 如果目标类是接口或者就是一个代理类则使用JDK动态代理  
      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
         return new JdkDynamicAopProxy(config);
      }
      // 其他使CGLIB动态代理
      return new ObjenesisCglibAopProxy(config);
   }
   // 其他默认使用JDK代理
   else {
      return new JdkDynamicAopProxy(config);
   }
}

这里使用了JDK或者CGLIB代理,默认为JDK代理,如果目标类targetClass是接口或者是JDK代理类则直接使用JDK代理。JDK代理的核心是invoke,CGLIB代理的核心是callBack

JdkDynamicAopProxy的invoke流程,这里是说明核心代码


@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   Object oldProxy = null;
   boolean setProxyContext = false;


   TargetSource targetSource = this.advised.targetSource;
   Object target = null;


   try {
       // equals方法不代理
      if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
         return equals(args[0]);
      }
      // hashCode方法不代理
      else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
         return hashCode();
      }
          // DecoratingProxy类不代理
      else if (method.getDeclaringClass() == DecoratingProxy.class) {
         // There is only getDecoratedClass() declared -> dispatch to proxy config.
         return AopProxyUtils.ultimateTargetClass(this.advised);
      }
      //  Advised类不代理
      else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
            method.getDeclaringClass().isAssignableFrom(Advised.class)) {
         // Service invocations on ProxyConfig with the proxy config...
         return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
      }
      Object retVal;
      if (this.advised.exposeProxy) {
         // 上下文代理对象的处理,设置的是当前对象
         oldProxy = AopContext.setCurrentProxy(proxy);
         setProxyContext = true;
      }
      target = targetSource.getTarget();
      Class<?> targetClass = (target != null ? target.getClass() : null);

      // 获取该方法的拦截器链
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);


      //不存在增强器,则直接反射调用
      if (chain.isEmpty()) {
         Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
         retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
      }
      else {
         // 构建一个方法调用对象MethodInvocation
         MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
         // 开始调用
         retVal = invocation.proceed();
      }

      // 返回结果校验
      Class<?> returnType = method.getReturnType();
      if (retVal != null && retVal == target &&
            returnType != Object.class && returnType.isInstance(proxy) &&
            !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
         // 返回this
         retVal = proxy;
      }
      // 返回值不对抛出异常
      else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
         throw new AopInvocationException(
               "Null return value from advice does not match primitive return type for: " + method);
      }
      // 返回处理后的值
      return retVal;
   }
   finally {
      if (target != null && !targetSource.isStatic()) {
         // Must have come from TargetSource.
         targetSource.releaseTarget(target);
      }
      if (setProxyContext) {
         // 重置旧的代理对象.
         AopContext.setCurrentProxy(oldProxy);
      }
   }
}

ObjenesisCglibAopProxy的调用流程


protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
   enhancer.setInterceptDuringConstruction(false);
   enhancer.setCallbacks(callbacks);
   return (this.constructorArgs != null && this.constructorArgTypes != null ?
         enhancer.create(this.constructorArgTypes, this.constructorArgs) :
         enhancer.create());
}

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
   boolean exposeProxy = this.advised.isExposeProxy();
   boolean isFrozen = this.advised.isFrozen();
   boolean isStatic = this.advised.getTargetSource().isStatic();

   // AOP的拦截器 
   Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
     ...
}

方法级别的CallBack则核心在DynamicAdvisedInterceptor#intercept

@Override
@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();
   try {
      // 上下文暴露
      if (this.advised.exposeProxy) {
         // Make invocation available if necessary.
         oldProxy = AopContext.setCurrentProxy(proxy);
         setProxyContext = true;
      }
      target = targetSource.getTarget();
      Class<?> targetClass = (target != null ? target.getClass() : null);
      // 获取增强器链
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
      Object retVal;
     // 无增强器的处理,直接反射
      if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
         Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
         retVal = methodProxy.invoke(target, argsToUse);
      }
      else {
         // 构建CglibMethodInvocation并调用,
         retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
      }
      // 处理返回值
      retVal = processReturnType(proxy, target, method, retVal);
      return retVal;
   }
   finally {
      if (target != null && !targetSource.isStatic()) {
         targetSource.releaseTarget(target);
      }
      if (setProxyContext) {
         // Restore old proxy.
         AopContext.setCurrentProxy(oldProxy);
      }
   }
}

二者公共使用的逻辑,

  • 第一步: 构建一个拦截器链
  • 第二步: 拦截器链的链式调用
  • 第三步: 返回结果的处理

  • 拦截器链的构建:getInterceptorsAndDynamicInterceptionAdvice--->DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
      Advised config, Method method, @Nullable Class<?> targetClass) {

   AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
   // 获取增强器列表
   Advisor[] advisors = config.getAdvisors();
   List<Object> interceptorList = new ArrayList<>(advisors.length);
   Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
   Boolean hasIntroductions = null;

   for (Advisor advisor : advisors) {
      // 切入点增强器  
      if (advisor instanceof PointcutAdvisor) {
         PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
         // 类级别匹配
         if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
            // 方法匹配
            MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
            boolean match;
            if (mm instanceof IntroductionAwareMethodMatcher) {
               if (hasIntroductions == null) {
                  hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
               }
               match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
            }
            else {
               match = mm.matches(method, actualClass);
            }
            // 完全匹配
            if (match) {
               // 从注册表中获取方法拦截器 
               MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
               // 匹配器是动态匹配,含占位符 ,则在包装一层,待后续处理
               if (mm.isRuntime()) {
                  for (MethodInterceptor interceptor : interceptors) {
                     interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                  }
               }
               // 不是则直接添加
               else {
                  interceptorList.addAll(Arrays.asList(interceptors));
               }
            }
         }
      }
      // 引介增强,匹配类即可
      else if (advisor instanceof IntroductionAdvisor) {
         IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
         if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
            Interceptor[] interceptors = registry.getInterceptors(advisor);
            interceptorList.addAll(Arrays.asList(interceptors));
         }
      }
      // 从注册表中加载用户自定义的拦截器  
      else {
         Interceptor[] interceptors = registry.getInterceptors(advisor);
         interceptorList.addAll(Arrays.asList(interceptors));
      }
   }


   return interceptorList;
}

在这里有个核心代码:拦截器链的构建最终返回的是Interceptor(子接口MethodInterceptor)列表,也就是真正对代码增强的是拦截器

MethodInterceptor[] interceptors = registry.getInterceptors(advisor);

Interceptor[] interceptors = registry.getInterceptors(advisor);

  • 拦截器链的链式调用(方法的真正增强过程)ReflectiveMethodInvocation#proceed
@Override
@Nullable
public Object proceed() throws Throwable {
    // 链式处理
   if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
      return invokeJoinpoint();
   }

   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());
      // 此时参数匹配了再处理
      if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
         return dm.interceptor.invoke(this);
      }
      else {
         // 下一个链   
         return proceed();
      }
   }
   else {
      // 完全匹配好的,直接调用即可
      return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
   }
}

至此AOP所有流程完毕。