likes
comments
collection
share

spring源码4 -- 内置的后置处理器PostProcess加载源码

作者站长头像
站长
· 阅读数 11
可以学习到什么?
1. BeanFactoryPostProcessor调用过程源码剖析
2. 配置类的解析过程源码
3. 配置类@Configuration加与不加的区别
4. 重复beanName的覆盖规则
5. @ComponentScan的解析原理

一、研究目标: 解析spring如何加载配置类

我们经常会在一个类上打上@Configuration, @Component, @Bean等. 带有这些注解的类, 就是我们所说的配置类. 那么, spring启动的时候,是如何加载这些配置类的呢?

下面就以此为目的, 分析spring源码. 本节的内容是对上一节内容的实战分析, 同时更加详细的解读spring源码

我们知道, spring启动的时候做了3件事, 就是上面的三件事.

spring源码4 -- 内置的后置处理器PostProcess加载源码

第一件事: 调用this()自身的无参构造函数. 初始化了BeanDefinitionReader和BeanDefinitionScanner, 同时初始化了很多spring的原始后置处理器, 这些处理器是用来加载bean的

第二件事: 调用register(..) 注册配置类

第三件事: refresh(..) 这里包含了整个ioc创建bean的全生命周期, 今天重点看invokeBeanFactoryPostProcessors(beanFactory)加载配置类

二、准备工作: 自定义配置类MainConfig

我们先定义好要分析加载的配置类

package com.agony.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * 这是一个配置类,
 * 在配置类里面定义了扫描的包路径agony
 * 这是会将这个包下配置了注解的类扫描到ioc容器里面,成为一个成熟的bean
 */
@Configuration
@ComponentScan(basePackages = {"com.agony"})
public class MainConfig {
}

这个配置类很简单, 使用@ComponentScan注解指定了扫描的包. @Configuration指定当前是一个配置类.

接下来定义一个main方法, 加载配置类.

package com.agony.demo;

import com.agony.domain.Car;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainStarter {
   public static void main(String[] args) {
      // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
      AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStarter.class);
      // context.addBeanFactoryPostProcessor();
      Car car = (Car) context.getBean("car");
      System.out.println(car.getName());
      context.close();
   }
}

在main里, 通过AnnotationConfigurationApplicationContext读取配置类MainConfig.class.

配置类被传进来以后, 到底是怎么被解析的呢? 这就是我们分析的线索

始终不要忘记我们的整体架构图. 对照这个图来分析. 思路更清晰.

spring源码4 -- 内置的后置处理器PostProcess加载源码 下面, 从入口进入. 我们的入口就是这里

new AnnotationConfigApplicationContext(MainConfig.class);

下面进入AnnotationConfigApplicationContext的构造方法

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    // 进入构造函数, 首先调用自身的构造方法this();
    // 调用自身的构造方法之前, 要先调用父类的构造方法
    this();
    // register配置注册类
    register(componentClasses);
    // ioc容器刷新接口--非常重要
    refresh();
}

三、读取配置类后置处理器ConfigurationClassPostProcessor

3.1 调用this()无参构造函数

public AnnotationConfigApplicationContext() {
   StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
   /**todo:
    *  创建了一个Bean定义的读取器.
    *  完成了spring内部BeanDefinition的注册(主要是后置处理器)
    *  读取了很多spring自定义的配置(主要是后置处理器). 这些类都是spring的原始类.
    */
   this.reader = new AnnotatedBeanDefinitionReader(this);
   createAnnotatedBeanDefReader.end();
   /**todo:
    *  创建BeanDefinition扫描器
    *  可以用来扫描包或者类, 进而转换为bd
    *
    * todo:
    *  Spring默认的扫描包不是这个this.scanner对象
    *  而是自己new的一个ClassPathBeanDefinitionScanner
    *  Spring在执行工程后置处理器ConfigurationClassPostProcessor时, 去扫描包时会new一个ClassPathBeanDefinitionScanner
    *
    * todo:
    *  这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
    *  通过调用context.scan("包名");扫描处理配置类
    *  扫描
    */
   this.scanner = new ClassPathBeanDefinitionScanner(this);
}

在初始化AnnotatedBeanDefinitionReader(this);的时候, 注册了很多后置处理器

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
      BeanDefinitionRegistry registry, @Nullable Object source) {

   /*todo: 获取到beanFactory : DefaultListableBeanFactory和GenericApplicationContext都是BeanDefinitionRegistry接口的实现类*/
   DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
   /*todo: 判断beanFactory中是否有AnnotationAwareOrderComparator和ContextAnnotationAutowireCandidateResolver,没有则添加*/
   /**
    * (1) AnnotationAwareOrderComparator
    * 是OrderComparator的扩展,支持Spring的Ordered接口以及@Order@Priority注解.Ordered实例提供的order值覆盖静态定义的注解值(如果有)
    * (2) ContextAnnotationAutowireCandidateResolver:
    * 完成AutowireCandidateResolver策略接口的实现,支持限定符注释以及context.annotation包中的lazy注释驱动的惰性解析
    */
   if (beanFactory != null) {
      if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
         beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
      }
      if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
         beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
      }
   }
   /* todo: BeanDefinitionHolder: 为BeanDefinition设置名字和别名 */
   Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

   /* todo: 1. 如果registry中没有ConfigurationClassPostProcessor配置类后置处理器, 就添加一个 */
   if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
      def.setSource(source);
      /** 构建BeanDefinitionHolder, 并添加到beanDefs */
      /**
       * registry: BeanDefinitionRegistry注册器, 用于注册BeanDefinition
       * def: 刚刚构建的RootBeanDefinition
       * CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME: 构建BeanDefinition使用的beanName是org.springframework.context.annotation.internalConfigurationAnnotationProcessor
       */
      beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   /* todo: 2. 如果registry中, 没有AutowiredAnnotationBeanPostProcessor  Autowired注解bean的后置处理器, 则添加一个 */
   if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
      def.setSource(source);
      /** 构建BeanDefinitionHolder, 并添加到beanDefs */
      beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   /* todo: 3. 检查对JSR-250的支持, 如果registry中没有CommonAnnotationBeanPostProcessor通用注解后置处理器, 则添加一个 */
   // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
   if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
      def.setSource(source);
      /** 构建BeanDefinitionHolder, 并添加到beanDefs */
      beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   /* todo: 4. 检查对jpa的支持, 如果不包含internalPersistenceAnnotationProcessor, 持久化注解处理器, 就添加一个 */
   // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
   if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition();
      try {
         def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
               AnnotationConfigUtils.class.getClassLoader()));
      } catch (ClassNotFoundException ex) {
         throw new IllegalStateException(
               "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
      }
      def.setSource(source);
      /** 构建BeanDefinitionHolder, 并添加到beanDefs */
      beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   /* todo: 5. 检查对事件监听的支持, 如果不包含事件监听处理器internalEventListenerProcessor, 就添加一个 */
   if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
      def.setSource(source);
      /** 构建BeanDefinitionHolder, 并添加到beanDefs */
      beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
   }

   /* todo: 6. 如果不包含事件监听工厂处理器internalEventListenerFactory , 就添加一个 */
   if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
      def.setSource(source);
      /** 构建BeanDefinitionHolder, 并添加到beanDefs */
      beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
   }

   return beanDefs;
}

我们看到, 注册了6个原始RootBeanDefinition, 这些bean是spring自己提前定义好的, 他们的加载是整个spring的基础. 用于解析spring中其他的类

而这一次我们要研究配置类是如何被读取的, 所以重点关注的是下面这个后置处理器

ConfigurationClassPostProcessor.class

3.2 ConfigurationClassPostProcessor的继承结构

spring源码4 -- 内置的后置处理器PostProcess加载源码 可以看到ConfigurationClassPostProcessor是同时实现了BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor. 这一点我们需要记住, 后面会使用到

3.3 ConfigurationClassPostProcessor是如何被注册的

// 如果registry中没有ConfigurationClassPostProcessor配置类后置处理器, 就添加一个
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
    RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
    def.setSource(source);
    // 构建BeanDefinitionHolder, 并添加到beanDefs
    beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}

首先,构建了一个RootBeanDefinition. 然后调用了registerPostProcessor方法, 三个入参分别是

registry: BeanDefinitionRegistry注册器, 用于注册BeanDefinition

def: 刚刚构建的RootBeanDefinition

CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME: 构建BeanDefinition使用的beanName

/**
 * 到这里已经初始化了 Bean 容器,<bean/>的配置也相应的转换为了一个个BeanDefinition,然后注册了所有的BeanDefinition到beanDefinitionMap
 */
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {

   Assert.hasText(beanName, "Bean name must not be empty");
   Assert.notNull(beanDefinition, "BeanDefinition must not be null");

   if (beanDefinition instanceof AbstractBeanDefinition) {
      try {
         ((AbstractBeanDefinition) beanDefinition).validate();
      } catch (BeanDefinitionValidationException ex) {
         throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
               "Validation of bean definition failed", ex);
      }
   }
   // 所有的 Bean 注册后都会被放入到这个beanDefinitionMap 中,查看是否已存在这个bean
   /*todo:
    * 从BeanDefinition的一级缓存BeanDefinitionMap中读取BeanDefinition对象
    * 判断是否已经存在BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    */
   // 将ConfigurationClassPostProcessor放入到了beanDefinitionMap里面
   BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
   // 处理重复名称的 Bean 定义的情况
   /**这里,如果已经存在,说明被重复加载了, 那么后面加载的会覆盖前面加载的bean*/
   if (existingDefinition != null) {
      // 判断是否允许BeanDefinition重写
      // 如果不允许覆盖的话,抛异常
      if (!isAllowBeanDefinitionOverriding()) {
         throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
      }
      // 用框架定义的 Bean 覆盖用户自定义的 Bean
      else if (existingDefinition.getRole() < beanDefinition.getRole()) {
         // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
         if (logger.isInfoEnabled()) {
            logger.info("Overriding user-defined bean definition for bean '" + beanName +
                  "' with a framework-generated bean definition: replacing [" +
                  existingDefinition + "] with [" + beanDefinition + "]");
         }
      }
      // 用新的 Bean 覆盖旧的 Bean
      else if (!beanDefinition.equals(existingDefinition)) {
         if (logger.isDebugEnabled()) {
            logger.debug("Overriding bean definition for bean '" + beanName +
                  "' with a different definition: replacing [" + existingDefinition +
                  "] with [" + beanDefinition + "]");
         }
      } else {
         // log...用同等的 Bean 覆盖旧的 Bean
         if (logger.isTraceEnabled()) {
            logger.trace("Overriding bean definition for bean '" + beanName +
                  "' with an equivalent definition: replacing [" + existingDefinition +
                  "] with [" + beanDefinition + "]");
         }
      }
      // 覆盖一级缓存的bean定义
      this.beanDefinitionMap.put(beanName, beanDefinition);
   } else {
      // 处理循环引用的问题
      // 判断是否已经有其他的 Bean 开始初始化了.注意,"注册Bean" 这个动作结束,Bean 依然还没有初始化 在 Spring 容器启动的最后,会预初始化所有的 singleton beans
      if (hasBeanCreationStarted()) {
         // Cannot modify startup-time collection elements anymore (for stable iteration)
         synchronized (this.beanDefinitionMap) {
            this.beanDefinitionMap.put(beanName, beanDefinition);
            List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
            updatedDefinitions.addAll(this.beanDefinitionNames);
            updatedDefinitions.add(beanName);
            this.beanDefinitionNames = updatedDefinitions;
            removeManualSingletonName(beanName);
         }
      } else {
         // Still in startup registration phase
         // 将 BeanDefinition 放到这个 map 中,这个 map 保存了所有的 BeanDefinition
         this.beanDefinitionMap.put(beanName, beanDefinition);
         // 这是个 ArrayList,所以会按照 bean 配置的顺序保存每一个注册的 Bean 的名字
         this.beanDefinitionNames.add(beanName);
         // 这是个 LinkedHashSet,代表的是手动注册的 singleton bean
         removeManualSingletonName(beanName);
      }
      this.frozenBeanDefinitionNames = null;
   }

   if (existingDefinition != null || containsSingleton(beanName)) {
      resetBeanDefinition(beanName);
   } else if (isConfigurationFrozen()) {
      clearByTypeCache();
   }
}

这里面的关键代码是, 将ConfigurationClassPostProcessor放入到了beanDefinitionMap里面

下面的else是处理循环引用的问题, 暂时先不要看

3.4 对照整体框架, 我们知道ConfigurationClassPostProcessor被解析成beanDefinition放入到BeanDefinitionMap中了

spring源码4 -- 内置的后置处理器PostProcess加载源码

3.5 初始化ClassPathBeanDefinitionScanner

在this()构造方法里, 还初始化了ClassPathBeanDefinitionScanner, 这里只说一句.

this.scanner = new ClassPathBeanDefinitionScanner(this);

我们在扫描配置类的时候, 确实使用的是ClassPathBeanDefinitionScanner, 但是, 不是this.scanner对象. 而是自己new的一个ClassPathBeanDefinitionScanner.

这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法

通过调用context.scan("package name");扫描处理配置类

使用方式如下:

public static void main(String[] args) {
    // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
    context.scan("package");
    Car car = (Car) context.getBean("car");
    System.out.println(car.getName());
    context.close();
}

spring源码4 -- 内置的后置处理器PostProcess加载源码

到目前为止完成了后置处理器注册为BeanDefinition

 

备注:

ConfigurationClassPostProcessor是一个工具类, 这个类的作用是解析配置类.

工具类有了, 那么还得有主角呀, 那就是我们上面的配置类. 下面看看配置类的加载

四、读取自定义配置类MainConfig

注册配置类,入口自然是这里了

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
   /* todo: 调用自身的构造方法之前, 要先调用父类的构造方法 ---> this.beanFactory = new DefaultListableBeanFactory(); */
   /* todo: 然后调用自身的构造方法this() ---> 一共做了两件事情*/
   this();
   // 调用注册器, 这里会加载两个BeanDefinitionReader和BeanDefinitionScanner. 这两位的角色是什么呢? 可以回忆一下之前的框架图
   register(componentClasses);
   /*todo:ioc容器刷新接口--非常重要*/
   refresh();
}

跟踪进去找到doRegisterBean(...)方法

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
      @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
      @Nullable BeanDefinitionCustomizer[] customizers) {

   /*todo:将入参beanClass构建成AnnotatedGenericBeanDefinition对象*/
   AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
   if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
      return;
   }

   abd.setInstanceSupplier(supplier);
   // 读取配置类的元数据
   ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
   abd.setScope(scopeMetadata.getScopeName());
   String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

   /*todo:处理通用定义注解*/
   AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
   if (qualifiers != null) {
      for (Class<? extends Annotation> qualifier : qualifiers) {
         if (Primary.class == qualifier) {
            abd.setPrimary(true);
         }
         else if (Lazy.class == qualifier) {
            abd.setLazyInit(true);
         }
         else {
            abd.addQualifier(new AutowireCandidateQualifier(qualifier));
         }
      }
   }
   if (customizers != null) {
      for (BeanDefinitionCustomizer customizer : customizers) {
         customizer.customize(abd);
      }
   }

   // 将MainConfig.java配置类进行解析.放到BeanDefinitionHolder
   BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
   definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
   BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

重点就是这句话, 其他可以略过, 因为我们的配置类很简单, 直接看 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder,this.registry);

我们找到 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());方法, 进入到DefaultListableBeanFactory查看方法, 这个方法之前我们已经调用过一次

就是在注册ConfigurationClassPostProcessor的时候, 我们需要将其解析为BeanDefinition然后放到BeanDefinitionMap中, 这里也是一样的, 将我们的配置类MainConfig解析成BeanDefinition放入到BeanDefinitionMap中.

这里的代码在整个框架中处于什么位置呢? 将MainConfig解析为BeanDefinition放入到BeanDefinitionMap中

spring源码4 -- 内置的后置处理器PostProcess加载源码 以上两步, 一个是将ConfigurationClassPostProcessor配置类后置处理器, 也就是解析配置的工具类, 解析成BeanDefinition放入到BeanDefinitionMap中

另一个是将我们的目标配置类MainConfig加载到内存, 组装成BeanDefinition放入到BeanDefinitionMap中.

到这里,我们完成了两步.

spring源码4 -- 内置的后置处理器PostProcess加载源码 第一步: 准备工具类ConfigurationClassPostProcessor

第二步: 准备配置类MainConfig.

接下来, 就是要使用工具类来解析配置类MainConfig了

五、调用bean工厂的后置处理器invokeBeanFactoryPostProcessors(beanFactory);

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    // 进入构造函数, 首先调用自身的构造方法this();
    // 调用自身的构造方法之前, 要先调用父类的构造方法
    this();
    // register配置注册类
    register(componentClasses);
    // ioc容器刷新接口--非常重要
    refresh();
}

在refresh()中有很多步骤, 我们重点来看invokeBeanFactoryPostProcessors(beanFactory);

@Override
public void refresh() throws BeansException, IllegalStateException {
   // 为了避免refresh()还没结束,再次发起启动或者销毁容器引起的冲突
   synchronized (this.startupShutdownMonitor) {
      StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

      // Prepare this context for refreshing.做一些准备工作,记录容器的启动时间、标记“已启动”状态、检查环境变量等
      /*todo: 1.准备刷新上下文环境*/
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      // 乍一看这个方法也没几行代码,但是这个方法负责了BeanFactory的初始化、Bean的加载和注册等事件
      /*todo: 2.获取告诉子类初始化bean工厂, 不同工厂不同实现*/
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      // 这个方法主要会设置BeanFactory的类加载器、添加几个 BeanPostProcessor、手动注册几个特殊的bean
      /*todo: 3.对bean工厂进行填充属性*/
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         /**
          * 这个比较简单,又是Spring的一个扩展点
          * 如果有Bean实现了BeanFactoryPostProcessor接口,
          * 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。
          * 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
          */
         /*todo: 4.Spring开放接口 留给子类去实现该接口*/
         postProcessBeanFactory(beanFactory);

         StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
         // Invoke factory processors registered as beans in the context.
         // 调用BeanFactoryPostProcessor各个实现类的postProcessBeanFactory(factory) 方法
         /*todo: 5.调用我们的bean工厂的后置处理器:  (1) 会再次class扫描成BeanDefinition*/
         /**
          * 调用bean工厂的后置处理器
          * 我们之前在Reader的时候读取了很多创世纪的PostProcessor后置处理器.
          * 这里要调用bean工厂的后置处理器. 这么多创世纪的PostProcessor, 只有一个PostProcessor实现了
          * BeanFactoryPostProcessor. 那个类就是 ConfigurationClassPostProcessor
          * 前面已经将ConfigurationClassPostProcessor放入到BeanDefinitionMap中了,
          * 对应的BeanDefinitionName 是 internalConfigurationAnnotationProcessor
          */
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         /**
          * 又是一个扩展点
          * 注册 BeanPostProcessor 的实现类,注意不是BeanFactoryPostProcessor
          * 此接口有两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization分别会在Bean初始化之前和初始化之后得到执行
          */
         /*todo: 6.注册我们bean后置处理器*/
         registerBeanPostProcessors(beanFactory);
         beanPostProcess.end();

         // Initialize message source for this context.
         // 初始化当前 ApplicationContext 的 MessageSource,有想了解国际化的相关知识可以深入研究一下
         /*todo: 7.初始化国际化资源处理器*/
         initMessageSource();

         // Initialize event multicaster for this context.
         // 这个方法主要为初始化当前 ApplicationContext 的事件广播器
         /*todo: 8.初始化事件多播放器*/
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         // 又是一个扩展点,子类可以在这里来搞事情
         /*todo: 9.这个方法同样也是留个子类实现,其中springboot也是从这个方法进行tomcat的启动*/
         onRefresh();

         // Check for listener beans and register them.
         // 注册事件监听器
         /*todo: 10.把我们的事件监听器注册到多播器上*/
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons. 实例化剩余的单实例bean
         // 刚才我们提到了bean还没有初始化。这个方法就是负责初始化所有的没有设置懒加载的singleton bean
         /*todo: 11.实例化所有的非懒加载的单实例bean*/
         /**
          * 这个方法就是循环遍历BeanDefinitionMap, 调用getBean, 去生产bean
          */
         finishBeanFactoryInitialization(beanFactory);

         // Last step: publish corresponding event.
         // 最后一步: 发布相应的事件
         /*todo: 12.最后刷新容器 发布刷新事件(Spring cloud eureka也是从这里启动的)*/
         finishRefresh();
      } catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // Propagate exception to caller.
         throw ex;
      } finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         // 最后一步还是清除缓存
         resetCommonCaches();
         contextRefresh.end();
      }
   }
}

invokeBeanFactoryPostProcessors(beanFactory);看名字, 调用的是Bean工厂的后置处理器, 上面分析了, 初始化的时候初始化了很多spring原生的后置处理器, 这么多后置处理器, 其实, 只有一个后置处理器实现了BeanFactoryPostProcessor, 它就是ConfigurationClassPostProcessor, 还记得上面的结构图么, 拿下来, 再看一遍.

spring源码4 -- 内置的后置处理器PostProcess加载源码 这里调用的时候, 原生处理器只会调用ConfigurationClassPostProcessor

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   /**
    * 获取两处存储BeanFactoryPostProcessor的对象, 传入供接下来调用
    * 1. 当前bean工厂
    * 2. 和我们自己调用addBeanFactoryPostProcessor自定义BeanFactoryPostProcessor
    *
    * 参数: getBeanFactoryPostProcessors() 传了一个工厂的后置处理器的List, 这个时候list是空的
    * getBeanFactoryPostProcessors()里面的值是怎么来的呢?
    * 通过在自定义main方法中调用context.addBeanFactoryPostProcessor(...);来添加
    *
    * public static void main(String[] args) {
    *         // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
    *         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
    *         context.addBeanFactoryPostProcessor(...);
    *         Car car = (Car) context.getBean("car");
    *         System.out.println(car.getName());
    *         context.close();
    * }
    */
   PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

   // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
   // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
   if (!IN_NATIVE_IMAGE && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}

这里要调用bean工厂的后置处理器了. 看上面的注释, 注释写的很清晰.

在调用PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());的时候调用了getBeanFactoryPostProcessors()方法.

public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
   return this.beanFactoryPostProcessors;
}

getBeanFactoryPostProcessors() 返回的是一个工厂的后置处理器的List, 这个时候list是空的

getBeanFactoryPostProcessors()里面的值是怎么来的呢?

通过在自定义main方法中调用context.addBeanFactoryPostProcessor(...);来添加. 也就是通过main方法手动添加的beanFactoryPostProcessor. 如下所示

public static void main(String[] args) {
   // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
   AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
   context.addBeanFactoryPostProcessor(...);
   Car car = (Car) context.getBean("car");
   System.out.println(car.getName());
   context.close();
}

接下来重点来了. PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors**(beanFactory, getBeanFactoryPostProcessors()); 方法实现一共分为两大步:

第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义. 
(BeanDefinitionRegistryPostProcessor带注册功能的后置处理器)

第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器

第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义.

来看看源码是如何定义的. 重点看代码的注释, 每一部分的功能都有明确标出, 注释写的很详细

public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

   // Invoke BeanDefinitionRegistryPostProcessors first, if any.
   /**
    * 首先,调用BeanDefinitionRegistryPostProcessors的后置处理器
    * 定义已处理的后置处理器
    */
   Set<String> processedBeans = new HashSet<>();

   /**
    * 这里一共分为两大步:
    * 第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义. (BeanDefinitionRegistryPostProcessor带注册功能的后置处理器)
    * 第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器
    */
   /**********************第一步: 调用所有实现了BeanDefinitionRegistryPostProcessor接口的bean定义  begin****************************/
   // 判断beanFactory是否实现了BeanDefinitionRegistry, 实现了该结构就有注册和获取Bean定义的能力
   if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            registryProcessors.add(registryProcessor);
         }
         else {
            regularPostProcessors.add(postProcessor);
         }
      }

      // Do not initialize FactoryBeans here: We need to leave all regular beans
      // uninitialized to let the bean factory post-processors apply to them!
      // Separate between BeanDefinitionRegistryPostProcessors that implement
      // PriorityOrdered, Ordered, and the rest.
      /**
       * 这是一个集合, 存马上即将要被调用的BeanDefinitionRegistryPostProcessor
       */
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

      // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
      // 第一步, 调用实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors
      // 在所有创世纪的后置处理器中, 只有 internalConfigurationAnnotationProcessor 实现了 BeanDefinitionRegistryPostProcessors 和 PriorityOrdered
      String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         // 判断beanFactory是否实现了PriorityOrdered接口. 如果实现了,是最优先调用.
         // 在整个加载过程中,会调用四次BeanDefinitionRegistryPostProcessor, 而实现了PriorityOrdered的接口最先调用
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      /**
       * 第一次调用BeanDefinitionRegistryPostProcessors
       * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
       * 用于进行bean定义的加载 比如我们的包扫描 @import
       */
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
      // 处理完了,清空currentRegistryProcessors
      currentRegistryProcessors.clear();

      // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
      /** 第二步: 调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors。*/
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         /**这时实现了PriorityOrdered.class的postProcessor就不会再被加载进来了, 因为processedBeans.contains(ppName) == true*/
         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
            // 将其放入到currentRegistryProcessors, 马上就要被调用
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      // 对所有的处理器进行排序. 调用了Ordered的方法, 会返回排序(一个数字), 然后根据数字排序即可
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      /**
       * 第二次调用BeanDefinitionRegistryPostProcessors
       * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
       * 用于进行bean定义的加载 比如我们的包扫描 @import
       */
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
      currentRegistryProcessors.clear();

      // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
      /** 第三步. 调用没有实现任何优先级接口的 BeanDefinitionRegistryPostProcessor */
      boolean reiterate = true;
      while (reiterate) {
         reiterate = false;
         // 获取
         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         for (String ppName : postProcessorNames) {
            // 已处理过的postProcessor不再处理
            if (!processedBeans.contains(ppName)) {
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
               processedBeans.add(ppName);
               reiterate = true;
            }
         }
         sortPostProcessors(currentRegistryProcessors, beanFactory);
         registryProcessors.addAll(currentRegistryProcessors);
         /**
          * 第三次调用BeanDefinitionRegistryPostProcessors
          * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
          * 用于进行bean定义的加载 比如我们的包扫描 @import
          */
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
         currentRegistryProcessors.clear();
      }

      // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
      /**
       * 第四步:调用bean工厂的后置处理器
       * registryProcessors: 带有注册功能的bean工厂的后置处理器
       * regularPostProcessors: 不带注册功能的bean工厂的后置处理器
       */
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
   }

   else {
      // Invoke factory processors registered with the context instance.
      /**
       * 如果当前的beanFactory没有实现BeanDefinitionRegistry 说明没有注册Bean定义的能力
       * 那么就直接调用 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
       */
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
   }

   /**********************第一步: 调用所有实现了BeanDefinitionRegistryPostProcessor接口的bean定义  end****************************/

   /**********************第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器  begin****************************/
   // Do not initialize FactoryBeans here: We need to leave all regular beans
   // uninitialized to let the bean factory post-processors apply to them!
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

   // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   /** 优先排序的后置处理器 */
   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
      if (processedBeans.contains(ppName)) {
         // skip - already processed in first phase above
      }
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
   /** 首先, 调用有优先级排序的后置处理器 */
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

   // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
   /** 第二, 调用实现了Ordered排序的后置处理器 */
   List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
   for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

   // Finally, invoke all other BeanFactoryPostProcessors.
   /** 最后, 调用没有实现任何排序接口的beanFactory后置处理器 */
   List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
   for (String postProcessorName : nonOrderedPostProcessorNames) {
      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

   /**********************第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器  end****************************/
   // Clear cached merged bean definitions since the post-processors might have
   // modified the original metadata, e.g. replacing placeholders in values...
   beanFactory.clearMetadataCache();
}

spring源码4 -- 内置的后置处理器PostProcess加载源码

5.1 对照源码和上图, 我们来看第一次调用

// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 第一步, 调用实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors
// 在所有创世纪的后置处理器中, 只有 internalConfigurationAnnotationProcessor 实现了 BeanDefinitionRegistryPostProcessors 和 PriorityOrdered
String[] postProcessorNames =
      beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
   // 判断beanFactory是否实现了PriorityOrdered接口. 如果实现了,是最优先调用.
   // 在整个加载过程中,会调用四次BeanDefinitionRegistryPostProcessor, 而实现了PriorityOrdered的接口最先调用
   if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
      currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
      processedBeans.add(ppName);
   }
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
/**
 * 第一次调用BeanDefinitionRegistryPostProcessors
 * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
 * 用于进行bean定义的加载 比如我们的包扫描 @import
 */
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
// 处理完了,清空currentRegistryProcessors
currentRegistryProcessors.clear();

首先,拿到了所有实现了BeanDefinitionRegistryPostProcessor的后置处理器, 上面我们做过铺垫,只有ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor后置处理器

所以,这里过滤出来的postProcessorNames只有一个,就是ConfigurationClassPostProcessor, 接下来, 判断这个类是否实现了PriorityOrdered优先排序的接口, 如果实现了, 那么放入到currentRegistryProcessors中, 后面会进行调用.

接下来, 执行invokeBeanDefinitionRegistryPostProcessors

这是第一次调用BeanDefinitionRegistryPostProcessors

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());

5.2 第二次调用BeanDefinitionRegistryPostProcessors

// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
/** 第二步: 调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors。*/
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
   /**这时实现了PriorityOrdered.class的postProcessor就不会再被加载进来了, 因为processedBeans.contains(ppName) == true*/
   if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
      // 将其放入到currentRegistryProcessors, 马上就要被调用
      currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
      processedBeans.add(ppName);
   }
}
// 对所有的处理器进行排序. 调用了Ordered的方法, 会返回排序(一个数字), 然后根据数字排序即可
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
/**
 * 第二次调用BeanDefinitionRegistryPostProcessors
 * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
 * 用于进行bean定义的加载 比如我们的包扫描 @import
 */
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();

第二次调用的时候 ,依然是获取所有的实现了BeanDefinitionRegistryPostProcessor接口的后置处理器, 且这个处理器没有实现过PriorityOrdered也就是没有被上面调用过. 且实现了Ordered接口 这一类添加到currentRegistryProcessors集合中, 然后调用invokeBeanDefinitionRegistryPostProcessors处理

这是第二次调用BeanDefinitionRegistryPostProcessor

5.3 第三次调用BeanDefinitionRegistryPostProcessor

// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
/** 第三步. 调用没有实现任何优先级接口的 BeanDefinitionRegistryPostProcessor */
boolean reiterate = true;
while (reiterate) {
   reiterate = false;
   // 获取
   postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
   for (String ppName : postProcessorNames) {
      // 已处理过的postProcessor不再处理
      if (!processedBeans.contains(ppName)) {
         currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
         processedBeans.add(ppName);
         reiterate = true;
      }
   }
   sortPostProcessors(currentRegistryProcessors, beanFactory);
   registryProcessors.addAll(currentRegistryProcessors);
   /**
    * 第三次调用BeanDefinitionRegistryPostProcessors
    * 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
    * 用于进行bean定义的加载 比如我们的包扫描 @import
    */
   invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
   currentRegistryProcessors.clear();
}

第三次调用的是没有实现过任何排序接口的后置处理器.

并将其放入到currentRegistryProcessors, 然后执行invokeBeanDefinitionRegistryPostProcessors

5.4 第四次调用

// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
/**
 * 第四步:调用bean工厂的后置处理器
 * registryProcessors: 带有注册功能的bean工厂的后置处理器
 * regularPostProcessors: 不带注册功能的bean工厂的后置处理器
 */
// 调用BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法----为什么是调用BeanDefinitionRegistryPostProcessor?
// ConfigurationClassPostProcessor 实现了 BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessors
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 调用BeanFactoryPostProcessor 自己的(ConfigurationClassPostProcessor没有)
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

ConfigurationClassPostProcessor同时实现了BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessors, 调用的是invokeBeanFactoryPostProcessors

一共进行了4次调用

总结: 优先处理的是实现了PriorityOrdered的后置处理器, 然后调用实现了Order接口的后置处理器, 最后调用了没有实现任何排序方法的后置处理器. 最后调用Bean工厂的后置处理器【工厂类方法】.

下面我们来具体分析invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);

5.5 提问: 检验一下是否理解了上面四个步骤

1. ConfigurationClassPostProcessor会调用1234哪几步?

因为ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor和
BeanFactoryPostProcessor,PriorityOrdered, 因此会调用1,4

2. 如果自己定义了一个MyBeanFactoryPostProcessor会调用1234那几步?

@Component
public class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {
   @Override
   public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
   }

   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
   }
}

因为MyBeanFactoryPostProcessor是自定义的, 没有实现任何PriorityOrdered 或者 Order, 因此, 会调用3,4

六、详细研究第四步:invokeBeanFactoryPostProcessors(registryProcessors, beanFactory)的逻辑.

我们在这一步打个断点, 然后跟着断点一步一步点击进去

spring源码4 -- 内置的后置处理器PostProcess加载源码

spring源码4 -- 内置的后置处理器PostProcess加载源码 这是registryProcessors里面只有一个后置处理器, 就是ConfigurationClassPostProcessor.

然后进入到ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)方法

/**
 * Prepare the Configuration classes for servicing bean requests at runtime
 * by replacing them with CGLIB-enhanced subclasses.
 * 通过用CGLIB增强的子类替换bean请求来准备用于在运行时服务bean请求的配置类
 */
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   int factoryId = System.identityHashCode(beanFactory);
   if (this.factoriesPostProcessed.contains(factoryId)) {
      throw new IllegalStateException(
            "postProcessBeanFactory already called on this post-processor against " + beanFactory);
   }
   this.factoriesPostProcessed.add(factoryId);
   if (!this.registriesPostProcessed.contains(factoryId)) {
      // BeanDefinitionRegistryPostProcessor hook apparently not supported...
      // Simply call processConfigurationClasses lazily at this point then.
      processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
   }
   // 使用cglib配置类进行代理,因为@Bean方法到时候要进行创建Bean的实例
   enhanceConfigurationClasses(beanFactory);
   beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}

这里先看enhanceConfigurationClasses(beanFactory)方法

/**
 * Post-processes a BeanFactory in search of Configuration class BeanDefinitions;
 * any candidates are then enhanced by a {@link ConfigurationClassEnhancer}.
 * Candidate status is determined by BeanDefinition attribute metadata.
 *
 * 后处理BeanFactory以搜索配置类BeanDefinitions; 然后通过ConfigurationClassEnhancer增强任何候选对象。
 * 候选状态由BeanDefinition属性元数据确定。
 * @see ConfigurationClassEnhancer
 */
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
   StartupStep enhanceConfigClasses = this.applicationStartup.start("spring.context.config-classes.enhance");
   Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
   for (String beanName : beanFactory.getBeanDefinitionNames()) {
      BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
      Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
      MethodMetadata methodMetadata = null;
      if (beanDef instanceof AnnotatedBeanDefinition) {
         methodMetadata = ((AnnotatedBeanDefinition) beanDef).getFactoryMethodMetadata();
      }
      if ((configClassAttr != null || methodMetadata != null) && beanDef instanceof AbstractBeanDefinition) {
         // Configuration class (full or lite) or a configuration-derived @Bean method
         // -> resolve bean class at this point...
         AbstractBeanDefinition abd = (AbstractBeanDefinition) beanDef;
         if (!abd.hasBeanClass()) {
            try {
               abd.resolveBeanClass(this.beanClassLoader);
            } catch (Throwable ex) {
               throw new IllegalStateException(
                     "Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
            }
         }
      }
      /**
       * 只有full版配置才会创建cglib代理
       * full是怎么来的呢? 我们使用@Configuration注解了, 在加载的时候, 就会设置为full
       * 当设置为full以后, 我们在调用的时候, 就会创建一个cglib动态代理.
       *
       * 为什么要创建动态代理呢?
       * 动态代理可以保证, 每次创建的bean对象只有一个
       *
       * 那么加@Configuration和不加本质上的区别是什么?
       * 当在配置类中一个@Bean使用方法的方式引入另一个Bean的时候, 如果不加@Configuration注解, 就会重复加载Bean
       * 如果加了@Configuration, 则会在这里创建一个cglib代理, 当调用了@Bean方法是会先检测容器中是否存在这个Bean, 如果不存在则创建, 存在则直接使用.
       */
      if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {
         if (!(beanDef instanceof AbstractBeanDefinition)) {
            throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
                  beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
         } else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) {
            logger.info("Cannot enhance @Configuration bean definition '" + beanName +
                  "' since its singleton instance has been created too early. The typical cause " +
                  "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +
                  "return type: Consider declaring such methods as 'static'.");
         }
         configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
      }
   }
   if (configBeanDefs.isEmpty()) {
      // nothing to enhance -> return immediately
      enhanceConfigClasses.end();
      return;
   }
   if (IN_NATIVE_IMAGE) {
      throw new BeanDefinitionStoreException("@Configuration classes need to be marked as " +
            "proxyBeanMethods=false. Found: " + configBeanDefs.keySet());
   }

   ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
   for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
      AbstractBeanDefinition beanDef = entry.getValue();
      // If a @Configuration class gets proxied, always proxy the target class
      beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
      // Set enhanced subclass of the user-specified bean class
      Class<?> configClass = beanDef.getBeanClass();
      Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
      if (configClass != enhancedClass) {
         if (logger.isTraceEnabled()) {
            logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " +
                  "enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
         }
         beanDef.setBeanClass(enhancedClass);
      }
   }
   enhanceConfigClasses.tag("classCount", () -> String.valueOf(configBeanDefs.keySet().size())).end();
}

判断是否需要进行cglib代理.

进行cglib代理的条件是, beanDefinition中属性configurationClass的值是full. 只有full版配置才会创建cglib代理

那么有下面几个问题:

问题1: full版本配置是什么呢?

我们使用@Configuration注解了, 在加载的时候, 就会将configurationClass属性设置为full.

当设置为full以后, 我们在调用的时候, 就会创建一个cglib动态代理.

问题2: 为什么要创建动态代理呢?

动态代理可以保证, 每次创建的bean对象只有一个

问题3:那么加@Configuration和不加本质上的区别是什么?

当在配置类中一个@Bean使用方法的方式引入另一个Bean的时候, 如果不加@Configuration注解, 就会重复加载Bean.

如果加了@Configuration, 则会在这里创建一个cglib代理, 当调用了@Bean方法是会先检测容器中是否存在这个Bean, 如果不存在则创建, 存在则直接使用.

问题4:full是怎么来的呢?

这是在上面调用invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);接口的时候, 标记的是full还是Lite

下面来看一下源码

spring源码4 -- 内置的后置处理器PostProcess加载源码 在这里一步,执行的时候,进行了这个类是full的还是lite,继续往下看

spring源码4 -- 内置的后置处理器PostProcess加载源码 此时满足条件的postProcessor只有一个, 那就是ConfigurationClassPostProcessor. 下面直接看ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()方法

spring源码4 -- 内置的后置处理器PostProcess加载源码 前面都是一些条件判断, 重点看processConfigBeanDefinitions(registry);

spring源码4 -- 内置的后置处理器PostProcess加载源码 在这里,这个方法判断了, 这个类是full的还是lite的. 下面直接上代码

public static boolean checkConfigurationClassCandidate(
      BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {

   String className = beanDef.getBeanClassName();
   if (className == null || beanDef.getFactoryMethodName() != null) {
      return false;
   }

   AnnotationMetadata metadata;
   // 获取元数据
   if (beanDef instanceof AnnotatedBeanDefinition &&
         className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
      // Can reuse the pre-parsed metadata from the given BeanDefinition...
      metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
   }
   else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
      // Check already loaded Class if present...
      // since we possibly can't even load the class file for this Class.
      Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
      if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||
            BeanPostProcessor.class.isAssignableFrom(beanClass) ||
            AopInfrastructureBean.class.isAssignableFrom(beanClass) ||
            EventListenerFactory.class.isAssignableFrom(beanClass)) {
         return false;
      }
      metadata = AnnotationMetadata.introspect(beanClass);
   }
   else {
      try {
         MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
         metadata = metadataReader.getAnnotationMetadata();
      }
      catch (IOException ex) {
         if (logger.isDebugEnabled()) {
            logger.debug("Could not find class file for introspecting configuration annotations: " +
                  className, ex);
         }
         return false;
      }
   }

   // 判断元数据中是否包含Configuration注解
   Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
   /**
    * 判断, proxyBeanMethods属性是否为true, 如果为true就是一个完全的类,
    * 也就是带有@Configuration注解, 设置Configuration_class属性为full
    *
    * proxyBeanMethods配置类是用来指定@Bean注解标注的方法是否使用代理,
    * 默认是true使用代理,直接从IOC容器之中取得对象;
    * 如果设置为false,也就是不使用注解,每次调用@Bean标注的方法获取到的对象和IOC容器中的都不一样,是一个新的对象,所以我们可以将此属性设置为false来提高性能。
    */
   if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
      beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
   }
   /**
    * 判断是不是带了@Component, @ComponentScan @Import @ImportResource @Bean注解,
    * 如果带有这几种注解, 就将其Configuration_class属性为lite类型的配置类
       */
   else if (config != null || isConfigurationCandidate(metadata)) {
      beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
   }
   else {
      return false;
   }

   // It's a full or lite configuration candidate... Let's determine the order value, if any.
   Integer order = getOrder(metadata);
   if (order != null) {
      beanDef.setAttribute(ORDER_ATTRIBUTE, order);
   }

   return true;
}

上面主要是获取元数据, 然后判断元数据中是否有Configuration注解. 如果有,返回其属性. 我们判断其属性中proxyBeanMethods是否true, 如果是true, 那么将其设置为full.

如果配置中带有@Component, @ComponentScan @Import @ImportResource @Bean这几种属性之一, 那么就将其设置为lite.

6.1: cglib动态代理做了什么事情呢?

不看源码的情况下, 简单可以理解为, 去ioc工厂里面通过getBean("car") 查询了看ioc中是否有这个对象, 如果有就取出来, 不再另创建.

这也是@Configuration 和其他注解类似@Component和@ComponentScan的本质区别:

当在配置类中一个@Bean使用方法的方式引入另一个Bean的时候, 如果不加@Configuration注解, 就会重复创建Bean

如果加了@Configuration, 则会在这里创建一个cglib代理, 当调用了@Bean方法是会先检测容器中是否存在这个Bean, 如果不存在则创建, 存在则直接使用.

下面来看个例子

基础类:
public class Car  {
    private String name;
    private Tank tank;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Tank getTank() {
        return tank;
    }

    public void setTank(Tank tank) {
        this.tank = tank;
    }
}

public class Tank {
    private String name;

    public Tank() {
        System.out.println("创建一个tank");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

这是定义的car和tank的基础类

@Configuration
@ComponentScan(basePackages = {"com.agony"})
public class MainConfig {
    @Bean("car")
    public Car car() {
        Car car = new Car();
        car.setName("zhangsan");
        // 这里调用了Tank类, tank是通过@Bean注解注入的. 
        car.setTank(tank());
        return car;
    }

    @Bean
    public Tank tank() {
        return new Tank();
    }
}

当配置类使用了@Configuration注解的时候, 运行main方法

public class MainStarter {
    public static void main(String[] args) {
        // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
        context.scan("package");
        //context.addBeanFactoryPostProcessor();
        Car car = (Car) context.getBean("car");
        Car car2 = (Car) context.getBean("car");
        System.out.println(car.getName());
        context.close();
    }
}

spring源码4 -- 内置的后置处理器PostProcess加载源码

当去掉@Configuration注解的时候, 再次运行, 我们看到创建了两次tank

//@Configuration
@ComponentScan(basePackages = {"com.lxl.www.iocbeanlifecicle"})
public class MainConfig {

    @Bean("car")
    public Car car() {
        Car car = new Car();
        car.setName("zhangsan");
        // 这里调用了Tank类, tank是通过@Bean注解注入的. 
        car.setTank(tank());
        return car;
    }

    @Bean
    public Tank tank() {
        return new Tank();
    }
}

spring源码4 -- 内置的后置处理器PostProcess加载源码

在main方法中调用了两次 (Car) context.getBean("car");

在new一个对象的时候, 如果不去ioc容器中取, 那么每一次都会创建一个新的.

在ioc容器中, car对象只有一个, 但是在构建car的时候, 调用了tank, tank在ioc容器中却不一定只有一份. 只有使用了@Configuration, 表示需要使用cglib动态代理查找tank类, 保证ioc容器中只有一份.

七、详细研究四次调用中的第一次调用. 通过分析跟踪@ComponentScan注解是如何解析的

转载自:https://juejin.cn/post/7264920202851598373
评论
请登录