Spring源码解析七 (AOP深度解析)

目录

1. 目标bean实例化完成后调用初始化方法

2. 初始化方法执行之后应用后处理器(BeanPostProcessor)

3. 尝试扩展目标bean

4. 获取所有适合目标bean的所有Advisor

4.1 从容器获取所有已注册的增强

4.2 寻找所有的增强中适用于目标bean的增强

5. 创建代理(重点)

5.1 获取AOP代理(JdkDynamicAopProxy/CglibAopProxy)

5.2 通过AOP代理采用不同的策略为目标对象创建代理对象

5.2.1 使用JDK动态代理创建代理对象

5.2.2 使用CGLIB动态代理创建代理对象


在Spring容器中, bean实例化完成后, 会调用初始化方法; 在调用该bean实例的初始化方法前后会分别应用后处理器(BeanPostProcessors), 实际上是分别调用后处理器中postProcessBeforeInitialization()和postProcessAfterInitialization()方法, 尝试对bean进行扩展; 而AOP中的增强就是在调用后处理器中postProcessAfterInitialization()方法将增强进行织入的;

1. 目标bean实例化完成后调用初始化方法

AbstractAutowireCapableBeanFactory#initializeBean实现:

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
   ...
   if (mbd == null || !mbd.isSynthetic()) {
      /**
       * 应用后处理器(在bean初始化之前调用)
       */
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
      /**
       * 激活用户自定义的init方法, 完成初始化
       */
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   ...
   if (mbd == null || !mbd.isSynthetic()) {
      /**
       * 后处理器应用(在bean初始化之后调用)
       */
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }
   return wrappedBean;
}

2. 初始化方法执行之后应用后处理器(BeanPostProcessor)

(1) AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization实现:

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
   Object result = existingBean;
   //获取所有已注册的BeanPostProcessor,遍历执行每一个BeanPostProcessor中重写的postProcessAfterInitialization方法
   for (BeanPostProcessor processor : getBeanPostProcessors()) {
      /**
       * AOP应用:
       * {@link org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization(java.lang.Object, java.lang.String)}
       */
      Object current = processor.postProcessAfterInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}

分析: 获取所有注册到容器中的后处理器, 进行遍历执行postProcessAfterInitialization()方法, 尝试对bean进行扩展; 当遍历到processor为AnnotationAwareAspectJAutoProxyCreator实例时, 开始尝试对bean进行增强织入

(2) AbstractAutoProxyCreator#postProcessAfterInitialization实现:

(AbstractAutoProxyCreator为AnnotationAwareAspectJAutoProxyCreator的父类)

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
   if (bean != null) {
      //根据给定的bean的class和name构建出个key,格式:beanClassName_beanName
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (this.earlyProxyReferences.remove(cacheKey) != bean) {
         /**
          * 如果条件符合,则为bean生成代理对象
          */
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

分析:  根据bean的class属性和bean名称创建缓存key,  如果目标bean没有缓存在earlyProxyReferences集合中,  则开始尝试扩展目标bean


3. 尝试扩展目标bean

AbstractAutoProxyCreator#wrapIfNecessary实现:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        //如果已经处理过(targetSourcedBeans存放已经增强过的bean)
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        //advisedBeans的key为cacheKey,value为boolean类型,表示是否进行过代理
        //对于已经处理过的bean,不需要再次进行处理,节省时间
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        /**
         * 如果目标类代表一个基础设施类,基础设施类不应代理,或者配置了指定bean不需要自动代理
         * isInfrastructureClass(): 如果目标类继承自Advice、Pointcut、Advisor、AopInfrastructureBean
         *         或者带有@Aspect注解,或被Ajc(AspectJ编译器)编译都会被认定为内部基础设置类, 从而该目标类将会跳过扩展
         * shouldSkip(): 判断目标bean是否需要跳过{@link AspectJAwareAdvisorAutoProxyCreator#shouldSkip(java.lang.Class, java.lang.String)}
         */
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        /**
         * 获取所有适合该bean的增强Advisor
         * {@link AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean(java.lang.Class, java.lang.String, org.springframework.aop.TargetSource)
         */
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        //如果获取的增强不为null,则为该bean创建代理(DO_NOT_PROXY=null)
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            /**
             * 创建代理
             */
            Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }

        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

分析: 

  1. 如果已经处理过,则直接返回目标bean
  2. 对于内部配置相关类, 也直接返回目标bean, 并且将该目标bean标记为false, 后面再获取该bean时就直接返回了
  3. 获取所有适合该bean的增强Advisor
  4. 创建代理类

4. 获取所有适合目标bean的所有Advisor

(1) AbstractAutoProxyCreator#getAdvicesAndAdvisorsForBean实现:

protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
   /**
    * 获取合适的增强器
    */
   List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
   //数组为空,返回null
   if (advisors.isEmpty()) {
      return DO_NOT_PROXY;
   }
   return advisors.toArray();
}

(2) AbstractAdvisorAutoProxyCreator#findEligibleAdvisors实现:

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
   /**
    * 1. 获取所有的增强
    */
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   /**
    * 2. 寻找所有的增强中只用于bean的增强应用
    */
   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
   /**
    * 3. 模版方法,由子类拓展增强器(用作子类对已经查找完成的增强器进行拓展)
    * {@link AspectJAwareAdvisorAutoProxyCreator#extendAdvisors(java.util.List)}
    */
   extendAdvisors(eligibleAdvisors);
   /**
    * 4. 如果获取的Advisor集合eligibleAdvisors不为空,则根据优先级进行排序
    */
   if (!eligibleAdvisors.isEmpty()) {
      eligibleAdvisors = sortAdvisors(eligibleAdvisors);
   }
   return eligibleAdvisors;
}

分析:

  1. 从容器获取所有已注册的增强
  2. 寻找所有的增强中适用于目标bean的增强应用
  3. 模版方法,由子类拓展增强器(用作子类对已经查找完成的增强器进行拓展)
  4. 如果获取的Advisor集合eligibleAdvisors不为空,则根据优先级进行排序

4.1 从容器获取所有已注册的增强

AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors实现:

@Override
protected List<Advisor> findCandidateAdvisors() {
   /**
    * 增强器两类处理:
    *  1. 通过<aop>标签添加的增强,这部分会在解析配置文件的时候添加到Spring容器中,只需要获取当前容器中Advisor类型的bean就可以获取到该类增强;
    *  2. 通过注解添加的增强,获取此类增强还需要对bean进行遍历解析
    */
   /**
    * 在这里调用父类方法加载配置文件中的AOP声明
    */
   List<Advisor> advisors = super.findCandidateAdvisors();
   // Build Advisors for all AspectJ aspects in the bean factory.
   if (this.aspectJAdvisorsBuilder != null) {
      /**
       * 获取Bean的注解增强的功能
       */
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   }
   return advisors;
}

分析: 

  1. 首先尝试加载配置文件中的AOP声明信息
  2. 接着加载使用注解配置的AOP声明信息

(1) AbstractAdvisorAutoProxyCreator#findCandidateAdvisors ==>BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans实现:

public List<Advisor> findAdvisorBeans() {
   String[] advisorNames = this.cachedAdvisorBeanNames;
   /**
    * 如果advisorNames为null, 说明还没有加载配置文件中的AOP声明
    * 如果advisorNames为{}, 说明在配置文件中没有进行AOP配置
    */
   if (advisorNames == null) {
      /**
       * 1. 获取所有增强器的名称
       */
      advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false);
      this.cachedAdvisorBeanNames = advisorNames;
   }
   if (advisorNames.length == 0) {
      return new ArrayList<>();
   }

   List<Advisor> advisors = new ArrayList<>();
   /**
    * 2. 遍历所有增强器的名称,将其实例化
    */
   for (String name : advisorNames) {
      if (isEligibleBean(name)) {
         if (this.beanFactory.isCurrentlyInCreation(name)) {
          ...
         }
         else {
            try {
               /**
                * 实例化切面bean, 并添加到advisors集合中
                */
               advisors.add(this.beanFactory.getBean(name, Advisor.class));
            }
            ...
         }
      }
   }
   return advisors;
}

分析: 

  1. 如果获取到了相关切面类, 则进行实例化解析
  2. 如果没有获取到则返回空集合

(2) BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors实现:

public List<Advisor> buildAspectJAdvisors() {
   //先尝试从缓存中获取
   List<String> aspectNames = this.aspectBeanNames;

   if (aspectNames == null) {
      synchronized (this) {
         aspectNames = this.aspectBeanNames;
         if (aspectNames == null) {
            /**
             * advisors集合存储容器中所有的切面类中定义的增强/通知Advice (注意是增强/通知, 没有切入点)
             */
            List<Advisor> advisors = new ArrayList<>();
            aspectNames = new ArrayList<>();
            //获取所有的beanName
            String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                  this.beanFactory, Object.class, true, false);
            /**
             * 遍历所有的beanName,找出添加了@Aspect的类, 进行解析,注册   <===== 重点
             */
            for (String beanName : beanNames) {
               //不合法的bean则略过,由子类定义规则,默认返回true
               if (!isEligibleBean(beanName)) {
                  continue;
               }
               //获取对应的bean类型
               Class<?> beanType = this.beanFactory.getType(beanName);
               if (beanType == null) {
                  continue;
               }
               /**
                * 如果存在@Aspect注解的类
                */
               if (this.advisorFactory.isAspect(beanType)) {
                  aspectNames.add(beanName);
                  //保存bean类型以及@Aspect注解信息
                  AspectMetadata amd = new AspectMetadata(beanType, beanName);
                  //检查@Aspect注解的value值,验证生成的增强是否是单例
                  if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                     MetadataAwareAspectInstanceFactory factory =
                           new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                     /**
                      * classAdvisors集合存储的是该切面类中的所有的增强/通知
                      * {@link ReflectiveAspectJAdvisorFactory#getAdvisors(MetadataAwareAspectInstanceFactory)}
                      */
                     List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                     //如果bean是单例,则缓存bean的增强器
                     if (this.beanFactory.isSingleton(beanName)) {
                        this.advisorsCache.put(beanName, classAdvisors);
                     }
                     //bean非单例,只能缓存bean对应的增强器创建工厂
                     else {
                        this.aspectFactoryCache.put(beanName, factory);
                     }
                     advisors.addAll(classAdvisors);
                  }
                  /**
                   * 切面创建模式非单例
                   */
                  else {
                     //如果切面是非单例,但是bean是单例,抛出异常
                     if (this.beanFactory.isSingleton(beanName)) {
                        throw new IllegalArgumentException("Bean with name '" + beanName +
                              "' is a singleton, but aspect instantiation model is not singleton");
                     }
                     MetadataAwareAspectInstanceFactory factory =
                           new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                     this.aspectFactoryCache.put(beanName, factory);
                     //获取所有切面
                     advisors.addAll(this.advisorFactory.getAdvisors(factory));
                  }
               }
            }
            this.aspectBeanNames = aspectNames;
            return advisors;
         }
      }
   }
   /**
    * 如果不是第一次解析切面,证明增强器已经被缓存过了,会执行下面的代码,查询缓存
    */
   if (aspectNames.isEmpty()) {
      return Collections.emptyList();
   }
   //记录在缓存中
   List<Advisor> advisors = new ArrayList<>();
   for (String aspectName : aspectNames) {
      List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
      if (cachedAdvisors != null) {
         advisors.addAll(cachedAdvisors);
      }
      else {
         MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
         advisors.addAll(this.advisorFactory.getAdvisors(factory));
      }
   }
   return advisors;
}

分析: 

  1. 先尝试从缓存中获取, 如果获取成功则直接返回
  2. 如果没有从缓存获取到, 则遍历所有已注册的beanName, 对于添加@Aspect的类进行解析, 获取到该切面中的所有增强/通知(解析过程比较复杂,这里不再赘述, 感兴趣的可以自己看一下)
  3. 将解析之后的所有增强存储在List集合中, 并加入缓存, 后面可以直接通过缓存获取

4.2 寻找所有的增强中适用于目标bean的增强

AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply ==> AopUtils#findAdvisorsThatCanApply实现

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
   if (candidateAdvisors.isEmpty()) {
      return candidateAdvisors;
   }
   /**
    * eligibleAdvisors: 存储可以应用于目标类的增强
    * canApply(candidate, clazz): 判断候选增强是否适用于目标类
    */
   List<Advisor> eligibleAdvisors = new ArrayList<>();
   for (Advisor candidate : candidateAdvisors) {
      if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
         eligibleAdvisors.add(candidate);
      }
   }
   boolean hasIntroductions = !eligibleAdvisors.isEmpty();
   for (Advisor candidate : candidateAdvisors) {
      if (candidate instanceof IntroductionAdvisor) {
         // already processed
         continue;
      }
      if (canApply(candidate, clazz, hasIntroductions)) {
         eligibleAdvisors.add(candidate);
      }
   }
   return eligibleAdvisors;
}

5. 创建代理(重点)

AbstractAutoProxyCreator#createProxy实现:

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

   if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
      AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
   }
   /**
    * 创建代理工厂, 将增强相关配置包装在代理工厂中
    */
   ProxyFactory proxyFactory = new ProxyFactory();
   proxyFactory.copyFrom(this);

   if (!proxyFactory.isProxyTargetClass()) {
      if (shouldProxyTargetClass(beanClass, beanName)) {
         proxyFactory.setProxyTargetClass(true);
      }
      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);
   }
   /**
    * 通过proxyFactory获取AopProxy
    */
   return proxyFactory.getProxy(getProxyClassLoader());
}

分析:

  1. 将增强相关信息封装到ProxyFactory实例中
  2. 通过proxyFactory获取代理对象, 并返回

ProxyFactory#getProxy(java.lang.ClassLoader)实现:

public Object getProxy(@Nullable ClassLoader classLoader) {
   /**
    * 1. 代理类获取:
    *{@link ProxyCreatorSupport#createAopProxy()}
    * createAopProxy():
    *      ProxyFactory的父类ProxyCreatorSupport中的方法,父类ProxyCreatorSupport中维护着变量AopProxyFactory,
    *      DefaultAopProxyFactory是AopProxyFactory(接口)的实现类, 通过DefaultAopProxyFactory#createAopProxy()根据条件获取JdkDynamicAopProxy或CglibAopProxy实例
    *
    * 2. 代理目标类:
    * JDK动态代理
    * {@link JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)}
    * CGLIB动态代理
    * {@link CglibAopProxy#getProxy(java.lang.ClassLoader)}
    * getProxy(classLoader): 生成代理对象
    */
   return createAopProxy().getProxy(classLoader);
}

5.1 获取AOP代理(JdkDynamicAopProxy/CglibAopProxy)

ProxyCreatorSupport#createAopProxy实现:

protected final synchronized AopProxy createAopProxy() {
   ...
   /**
    * {@link org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy(org.springframework.aop.framework.AdvisedSupport)}
    * ProxyFactory的父类ProxyCreatorSupport中的方法,父类ProxyCreatorSupport中维护着变量AopProxyFactory,
    * DefaultAopProxyFactory是AopProxyFactory(接口)的实现类, 通过DefaultAopProxyFactory#createAopProxy()
    * 根据条件获取JdkDynamicAopProxy或CglibAopProxy实例, 所以创建代理类是可以传递this
    */
   return getAopProxyFactory().createAopProxy(this);
}

分析:  前面将增强相关配置信息封装到ProxyFactory中, 而ProxyCreatorSupportProxyFactory的父类, 父类ProxyCreatorSupport中维护着变量AopProxyFactory, DefaultAopProxyFactory是AopProxyFactory(接口)的实现类, 通过DefaultAopProxyFactory#createAopProxy()方法根据条件获取JdkDynamicAopProxy或CglibAopProxy实例, 所以创建代理类时通过传递this来传递增强/通知信息

DefaultAopProxyFactory#createAopProxy实现:

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
   /**
    * config.isOptimize(): 代理是否应执行积极的优化 (默认:false)
    * config.isProxyTargetClass(): 是否直接代理目标类以及任何接口 (默认:false); 如果配置<aop:aspectj-autoproxy proxy-target-class="true" />则强制使用CGLIB代理
    * hasNoUserSuppliedProxyInterfaces(config): 目标类是否有实现的接口,没有的话返回true (JDK动态代理基于接口,所以只有目标类存在接口才会使用JDK动态代理)
    */
   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);
      }
      return new ObjenesisCglibAopProxy(config);
   }
   else {
      return new JdkDynamicAopProxy(config);
   }
}

 分析:   该方法中根据条件去判断使用哪一种代理方式, 因此可知Spring中没有默认的生成代理的方式, Spring会根据目标对象的条件以及相关配置使用对应的动态代理, 这里注意, 并不是我们配置了<aop:aspectj-autoproxy proxy-target-class="true" />, 就Spring就一定会使用CGLIB动态代理,  如果目标类是接口,或者目标类是一个代理类, 那么即使做了上面的配置, Spring也会使用JDK动态代理;

5.2 通过AOP代理采用不同的策略为目标对象创建代理对象

对于JDK动态代理和CGLIB动态代理不太明白的伙伴可以看这两篇博客:

  1. JDK动态代理实现原理
  2. CGLIB动态代理实现原理

 

5.2.1 使用JDK动态代理创建代理对象

JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)实现:

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
   /**
    * 1. 获取所有被代理的接口(JDK动态代理基于接口)
    */
   Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
   /**
    * 2. 遍历所有代理接口中的方法,查找到某个接口中如果存在equals()和hashCode()方法,则进行标识, 如果标识为true,则后面会对这两个方法进行代理
    */
   findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
   /**
    * 3. 创建代理对象并返回
    *    注意: 在newProxyInstance()方法中传入的是this, 说明JdkDynamicAopProxy实现了InvocationHandler接口,
    *    并重写的invoke()方法, 那么增强的织入是在invoke()方法中实现的
    *    {@link JdkDynamicAopProxy#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])}
    */
   return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

分析:

  1. 获取所有被代理的接口(JDK动态代理基于接口)
  2. 遍历所有代理接口中的方法, 查找到目标类的某个接口中如果存在equals()和hashCode()方法,  则进行标识(说明目标类中的这两个方法时实现该接口的而不是Object的);  如果标识为true, 则后面会对这两个方法进行代理,  如果为false, 则后面忽略目标类中的equals()和hashCode()方法,认为这两个方法是基于超类Object的, 不进行增强
  3. 创建代理对象并返回; 注意: 在newProxyInstance()方法中传入的是this, 说明JdkDynamicAopProxy实现了InvocationHandler接口, 并重写的invoke()方法, 那么增强的织入是在invoke()方法中实现的  
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable 

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 {
      if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
         //目标本身不实现equals()方法
         return equals(args[0]);
      }
      else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
         //目标本身不实现hashCode()方法
         return hashCode();
      }
      else if (method.getDeclaringClass() == DecoratingProxy.class) {
         return AopProxyUtils.ultimateTargetClass(this.advised);
      }
      else if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
         return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
      }

      Object retVal;

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

      //目标类实例
      target = targetSource.getTarget();
      //目标类Class
      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);
         /**
          * 通过拦截器链进入连接点
          * {@link ReflectiveMethodInvocation#proceed()}
          */
         retVal = invocation.proceed();
      }

      /**
       * 返回信息处理
       */
      Class<?> returnType = method.getReturnType();
      if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
         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()) {
         targetSource.releaseTarget(target);
      }
      if (setProxyContext) {
         AopContext.setCurrentProxy(oldProxy);
      }
   }
}

分析:

  1. 对于不需要增强的类直接返回
  2. 创建一个MethodInvocation实例,该实例中维护这代理方法和拦截器链相关信息
  3. 通过拦截器链进入连接点, 执行增强方法, 以及切入点方法 (织入)    <==== 重点

ReflectiveMethodInvocation#proceed实现:

@Override
@Nullable
public Object proceed() throws Throwable {
   /**
    * currentInterceptorIndex: 当前需要执行拦截器在集合中位置, 默认为-1
    * 当最后一个拦截器执行完之后, 回调该方法才会执行切入点方法
    */
   if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
      /**
       * 执行切入点
       */
      return invokeJoinpoint();
   }
   /**
    * 根据索引获取到拦截器; 每调用一次proceed(), 会获取到下一个拦截器,然后进行处理
    */
   Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
   /**
    * 如果获取到的增强是内部框架类
    */
   if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
      InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
      if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
         return dm.interceptor.invoke(this);
      }
      else {
         //如果动态匹配失败,则跳过该拦截器,执行下一个(递归)
         return proceed();
      }
   }
   else {
      /**
       * 执行每个拦截器, 会先执行前置通知,再执行后置通知
       * 后置增强: {@link AspectJAfterAdvice#invoke(org.aopalliance.intercept.MethodInvocation)}
       * 前置增强: {@link MethodBeforeAdviceInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)}
       */
      return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
   }
}

分析:

  1. 当拦截器链中最后一个拦截器执行完之后, 回调该方法会执行切入点方法
  2. 根据索引获取到拦截器; 每调用一次proceed(), 会获取到下一个拦截器, 然后进行处理
  3. 如果获取到的增强是内部框架类, 则进行匹配, 如果匹配成功才会执行, 匹配失败直接执行下一个拦截器
  4. 激活拦截器

切入点方法执行: 

ReflectiveMethodInvocation#invokeJoinpoint ==> AopUtils#invokeJoinpointUsingReflection实现:

public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args) throws Throwable {
   try {
      /**
       * 利用反射执行目标方法
       */
      ReflectionUtils.makeAccessible(method);
      return method.invoke(target, args);
   }
  ...
}

后置通知方法执行:

AspectJAfterAdvice#invoke实现:

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
   try {
      /**
       * 如果是后置增强,则先调用MethodInvocation#proceed()方法, 执行其他增强, 等其他所有增强和切入点方法执行完成后,再执行后置增强
       *  {@link ReflectiveMethodInvocation#proceed()}
       */
      return mi.proceed();
   }
   finally {
      /**
       * 当所有拦截器执行完成之后,执行后置增强
       * 后置增强的执行是在finally块中,因此, 及时目标方法出现异常, 后置通知也会执行
       * 同理也可以知道, 异常增强方法是在catch块中执行的
       */
      invokeAdviceMethod(getJoinPointMatch(), null, null);
   }
}

分析:  这里是先调用MethodInvocation#proceed(), 先去执行其他拦截器, 等所有的拦截器执行结束会执行切入点方法, 等切入点方法执行完成之后, 才会执行该后置通知方法; 注意, 后置通知的执行是在finally块中执行的, 所以即使切入点方法执行时出现异常, 后置通知也仍然会执行;

前置通知方法执行:

MethodBeforeAdviceInterceptor#invoke实现:

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
   /**
    * 如果是前置通知,则先执行增强方法, 再调用proceed()去获取其他拦截器
    */
   this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
   /**
    * 调用MethodInvocation#proceed()执行切入点方法
    * {@link ReflectiveMethodInvocation#proceed()}
    */
   return mi.proceed();
}

分析: 对于前置通知, 就很简单了, 先执行前置通知方法, 然后调用MethodInvocation#proceed()执行去切入点方法 (前提是所有的拦截器都已经激活)

5.2.2 使用CGLIB动态代理创建代理对象

CglibAopProxy#getProxy(java.lang.ClassLoader)实现:

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
    try {
      //获取目标类Class对象
      Class<?> rootClass = this.advised.getTargetClass();
      Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
      //设置目标类为代理父类(CGLIB基于继承实现代理)
      Class<?> proxySuperClass = rootClass;
      //如果目标类也是CGLIB代理类,则设目标类的父类为代理父类
      if (ClassUtils.isCglibProxyClass(rootClass)) {
         proxySuperClass = rootClass.getSuperclass();
         //获取目标类的所有接口
         Class<?>[] additionalInterfaces = rootClass.getInterfaces();
         for (Class<?> additionalInterface : additionalInterfaces) {
            this.advised.addInterface(additionalInterface);
         }
      }

      // 验证类,根据需要编写日志消息
      validateClassIfNecessary(proxySuperClass, classLoader);

      //创建并配置CGLIB增强实例
      Enhancer enhancer = createEnhancer();
      if (classLoader != null) {
         enhancer.setClassLoader(classLoader);
         if (classLoader instanceof SmartClassLoader &&
               ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
            enhancer.setUseCache(false);
         }
      }
      //设置父类
      enhancer.setSuperclass(proxySuperClass);
      enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
      enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
      enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
      /**
       * 获取回调类信息,即增强
       */
      Callback[] callbacks = getCallbacks(rootClass);
      Class<?>[] types = new Class<?>[callbacks.length];
      for (int x = 0; x < types.length; x++) {
         types[x] = callbacks[x].getClass();
      }
   
      enhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
      enhancer.setCallbackTypes(types);

      /**
       * 生成代理类并创建代理实例
       * {@link ObjenesisCglibAopProxy#createProxyClassAndInstance(org.springframework.cglib.proxy.Enhancer, org.springframework.cglib.proxy.Callback[])}
       */
      return createProxyClassAndInstance(enhancer, callbacks);
   }
   ...
}


@Override
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
   //创建代理类
   Class<?> proxyClass = enhancer.createClass();
   Object proxyInstance = null;

   if (objenesis.isWorthTrying()) {
      try {
         /**
          * 实例化代理类
          */
         proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
      }
      ...
   }

   if (proxyInstance == null) {
      try {
         Constructor<?> ctor = (this.constructorArgs != null ?
               proxyClass.getDeclaredConstructor(this.constructorArgTypes) :
               proxyClass.getDeclaredConstructor());
         ReflectionUtils.makeAccessible(ctor);
         proxyInstance = (this.constructorArgs != null ?
               ctor.newInstance(this.constructorArgs) : ctor.newInstance());
      }
    ...
   }

   ((Factory) proxyInstance).setCallbacks(callbacks);
   /**
    * 代理类的执行方法
    * {@link DynamicAdvisedInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], org.springframework.cglib.proxy.MethodProxy)}
    */
   return proxyInstance;
}

分析:  对于CGLIB代理, 是基于目标类的, 给目标类生成一个子类, 重写目标类的方法, 在执行代理类的方法时会执行DynamicAdvisedInterceptor#intercept()方法; AOP增强的织入也是在这里面完成的;

CglibAopProxy.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;
      }
      // Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
      target = targetSource.getTarget();
      Class<?> targetClass = (target != null ? target.getClass() : null);
      /**
       * 1. 获取拦截器链
       */
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
      Object retVal;
      //检查我们是否只有一个InvokerInterceptor:没有真正的增强,只是对目标的发射调用。
      if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
         /**
          * 跳过创建MethodInvocation的方法:直接调用目标即可
          * 请注意,最终的调用者必须是InvokerInterceptor,因此我们知道它仅对目标执行反射操作,并且不执行热交换或奇特代理
          */
         Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
         retVal = methodProxy.invoke(target, argsToUse);
      }
      else {
         /**
          * 2.创建一个方法调用,执行目标方法
          *   (1) new CglibMethodInvocation():CglibMethodInvocation实例继承ReflectiveMethodInvocation
          *   (2) proceed():此处与JDK动态代理一样,都是通过ReflectiveMethodInvocation#proceed()方法完成增强的织入
          */
         retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
      }
      /**
       * 3. 处理返回值
       */
      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);
      }
   }
}

分析:

  1. 获取拦截器链
  2. 创建方法调用,执行目标方法; new CglibMethodInvocation(..): CglibMethodInvocation实例继承ReflectiveMethodInvocation; proceed(): 此处与JDK动态代理一样, 都是通过ReflectiveMethodInvocation#proceed()方法完成增强的织入
  3. 处理返回值

ReflectiveMethodInvocation#proceed实现:  

@Override
@Nullable
public Object proceed() throws Throwable {
   /**
    * currentInterceptorIndex: 当前需要执行拦截器在集合中位置, 默认为-1
    * 当最后一个拦截器执行完之后, 回调该方法才会执行切入点方法
    */
   if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
      /**
       * 执行切入点
       */
      return invokeJoinpoint();
   }
   /**
    * 根据索引获取到拦截器; 每调用一次proceed(), 会获取到下一个拦截器,然后进行处理
    */
   Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
   /**
    * 如果获取到的增强是内部框架类
    */
   if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
      InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
      if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
         return dm.interceptor.invoke(this);
      }
      else {
         //如果动态匹配失败,则跳过该拦截器,执行下一个(递归)
         return proceed();
      }
   }
   else {
      /**
       * 执行每个拦截器, 会先执行前置通知,再执行后置通知
       * 后置增强: {@link AspectJAfterAdvice#invoke(org.aopalliance.intercept.MethodInvocation)}
       * 前置增强: {@link MethodBeforeAdviceInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)}
       */
      return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
   }
}

分析: 对于两种动态代理方法, 增强的织入逻辑的实现都是一样的, 这里就不再赘述了, 可以参考上面JDK动态代理的织入过程

至此, Spring中AOP的实现解析完成!

 

相关文章:

     Spring源码解析一 (IOC容器初始化深度解析)

     Spring源码解析二 (IOC容器初始化方式一:XmlBeanFactory)

     Spring源码解析三 (IOC容器初始化方式二:ClassPathXmlApplicationContext)

     Spring源码解析四 (IOC容器初始化方式三: AnnotationConfigApplicationContext[包路径配置方式])

     Spring源码解析五 (IOC容器初始化方式四: AnnotationConfigApplicationContext[Java配置类方式])

     Spring源码解析六 (Bean的初始化)

     Spring源码解析七 (AOP深度解析)

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值