• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

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

武飞扬头像
agony
帮助1

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

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

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

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

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

学新通

第一件事: 调用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.

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

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

学新通 下面, 从入口进入. 我们的入口就是这里

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的继承结构

学新通 可以看到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中了

学新通

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();
}

学新通

到目前为止完成了后置处理器注册为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中

学新通 以上两步, 一个是将ConfigurationClassPostProcessor配置类后置处理器, 也就是解析配置的工具类, 解析成BeanDefinition放入到BeanDefinitionMap中

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

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

学新通 第一步: 准备工具类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, 还记得上面的结构图么, 拿下来, 再看一遍.

学新通 这里调用的时候, 原生处理器只会调用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();
}

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbaeee
系列文章
更多 icon
同类精品
更多 icon
继续加载