Spring启动流程-BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor

BeanFactoryPostProcessor

    BeanFactoryPostProcessor是Spring中一个重要的接口,依赖该接口可以实现对Spring中bean工厂中的beandefinition(未实例化)数据属性的修改。接口定义如下:

public interface BeanFactoryPostProcessor {
    //在初始化之后修改应用程序上下文的内部bean工厂。所有bean定义都已加载,实例化bean之前,可以覆盖或添加属性
   void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

官方文档对接口的说明如下:

  • 允许自定义修改应用程序上下文(容器)的未实例化bean的定义,修改上下文的底层bean工厂的bean属性值。
  • 应用程序上下文可以在其bean定义中自动检测BeanFactoryPostProcessor bean,并在创建任何其他bean之前应用它们。
  • BeanFactoryPostProcessor可以与bean定义交互并修改bean定义,但从不与bean实例交互。这样做可能会导致过早的bean实例化,破坏容器并导致意外的副作用。如果需要bean实例交互,考虑实BeanPostProcessor。

也就是说这个接口的作用是在容器中的bean实例化之前,对加载进容器的bean进行一些属性的修改。

BeanDefinitionRegistryPostProcessor

    BeanFactoryPostProcessor接口有一个子接口BeanDefinitionRegistryPostProcessor,BeanDefinitionRegistryPostProcessor实现了BeanFactoryPostProcessor,同时扩展了这个接口,其定义如下:

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { 
//在应用程序上下文中的bean注册器实例化之后可以对其进行修改,这可以向bean注册器中添加更多的bean定义 
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; 
}

  官方文档对于这个接口的说明如下:

  • 扩展了标准BeanFactoryPostProcessor SPI,允许在常规BeanFactoryPostProcessor postProcessBeanFactory方法执行之前向容器中注册更多的bean定义。特别是,BeanDefinitionRegistryPostProcessor可以注册更多的bean定义,这些定义反过来又定义了BeanFactoryPostProcessor实例。

 BeanDefinitionRegistryPostProcessor作为BeanFactoryPostProcessor的子接口,其postProcessBeanDefinitionRegistry方法会在所有BeanFactoryPostProcessor post-processing前执行。因此

  BeanDefinitionRegistryPostProcessor这个接口用于向容器中注册bean定义。

 

何时调用

那么这两个接口在何时被调用呢?在Spring启动过程,执行run方法,在创建Context之后,进入refreshContext方法,refreshContext方法如下: 

@Override public void refresh() throws BeansException, IllegalStateException { 
    synchronized (this.startupShutdownMonitor) { 
    // Prepare this context for refreshing. 
    prepareRefresh(); 
    // Tell the subclass to refresh the internal bean factory. 
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 
    //对beanFactory进行相关配置,例如context的ClassLoader和post-processors 
    prepareBeanFactory(beanFactory); 
    try { 
    // 允许context子类对beanFactory进行一些后置处理 
    postProcessBeanFactory(beanFactory); 
    // 调用容器中的BeanFactoryPostProcessor实现类的后置处理方法 
    invokeBeanFactoryPostProcessors(beanFactory); 
    // 向容器中注册BeanPostProcessor 
    registerBeanPostProcessors(beanFactory); 
    // Initialize message source for this context. 
    initMessageSource(); 
    // Initialize event multicaster for this context. 
    initApplicationEventMulticaster(); 
    // Initialize other special beans in specific context subclasses. 
    onRefresh(); 
    // Check for listener beans and register them. 
    registerListeners(); 
    // Instantiate all remaining (non-lazy-init) singletons. 
    finishBeanFactoryInitialization(beanFactory); 
    // Last step: publish corresponding event. 
    finishRefresh(); 
    } 
    ... 
    } 
}

    从代码中可以看出,在refresh方法中,会调用invokeBeanFactoryPostProcessors方法,这一步也是BeanFactoryPostProcessors和BeanDefinitionRegistryPostProcessor接口执行的地方,进入invokeBeanFactoryPostProcessors方法,这个方法使用了委托模式,将BeanFactoryPostProcessor的调用委托给了PostProcessorRegistrationDelegate执行,委托类invokeBeanFactoryPostProcessors代码如下,这个方法中会先依次执行BeanDefinitionRegistryPostProcessor接口实现类的postProcessBeanDefinitionRegistry方法,然后会调用BeanFactoryPostProcessors接口实现类的postProcessBeanFactory方法。

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

   Set processedBeans = new HashSet<>();

//首先调用BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
   if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      List regularPostProcessors = new ArrayList<>();
      List registryProcessors = new ArrayList<>();

//循环调用初始的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            registryProcessors.add(registryProcessor);
         }
         else {
            regularPostProcessors.add(postProcessor);
         }
      }

      //接着会去beanFactory中查找BeanDefinitionRegistryPostProcessor实现类,并按照
      //实现PriorityOrdered, Ordered的顺序依次调用执行
      //currentRegistryProcessors保存当前需要处理的BeanDefinitionRegistryPostProcessor list
      List currentRegistryProcessors = new ArrayList<>();

      // 首先, 调用实现PriorityOrdered优先级的BeanDefinitionRegistryPostProcessors
      String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
             //通过getBean方法实例化BeanDefinitionRegistryPostProcessor实现类
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            //添加到已处理的列表中,防止重复调用
            processedBeans.add(ppName);
         }
      }
      //根据order排序
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      //依次调用currentRegistryProcessors中的BeanDefinitionRegistryPostProcessor接口方法
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      // 第二步, 调用实现了Ordered接口的BeanDefinitionRegistryPostProcessors 
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      // 最后, 循环调用所有其他BeanDefinitionRegistryPostProcessors,只到没有新的BeanDefinitionRegistryPostProcessors出现
      //这里循环调用是因为,在调用BeanDefinitionRegistryPostProcessor过程中,可能会在bean注册器中不断的产生新的BeanDefinitionRegistryPostProcessor
      boolean reiterate = true;
      while (reiterate) {
         reiterate = false;
         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName)) {
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
               processedBeans.add(ppName);
               reiterate = true;
            }
         }
         sortPostProcessors(currentRegistryProcessors, beanFactory);
         registryProcessors.addAll(currentRegistryProcessors);
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
         currentRegistryProcessors.clear();
      }

      // 在处理完所有的BeanDefinitionRegistryPostProcessors之后,这里会调用之前实例化的BeanFactoryPostProcessor
      //这里因为BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,所以也会被调用
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
   }

   else {
      // Invoke factory processors registered with the context instance.
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
   }

    //处理剩余的BeanFactoryPostProcessor实现类
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

   // 需要根据BeanFactoryPostProcessor实现Order接口的顺序依次调用:priorityOrder->order—>nonOrder
   List priorityOrderedPostProcessors = new ArrayList<>();
   List orderedPostProcessorNames = new ArrayList<>();
   List 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);
      }
   }

   // 首先, 调用实现PriorityOrdere的BeanFactoryPostProcessors
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

   // 然后,调用实现Ordered的BeanFactoryPostProcessors.
   List orderedPostProcessors = new ArrayList<>();
   for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

   // 最后, 调用所有其他的BeanFactoryPostProcessors.
   List nonOrderedPostProcessors = new ArrayList<>();
   for (String postProcessorName : nonOrderedPostProcessorNames) {
      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

   // 清空缓存的bean definition
   beanFactory.clearMetadataCache();
}


小结:BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor提供了在容器实例化之后,在容器中bean的实例化之前对容器进行修改的入口。它们的区别是BeanDefinitionRegistryPostProcessor针对的是beanRegietry,BeanFactoryPostProcessor修改的是beanfactory。通过这两个接口,可以实现对bean的注册,bean实例化之前属性的修改等操作。例如Spring中的BeanDefinitionRegistryPostProcessor的实现类ConfigurationClassPostProcessor,通过这个类会将Spring中@Configuration、@Import、@Bean等注解的类扫描出来,并封装成BeanDefinition注册进容器中。

--文中源码基于Springboot2.1.4.RELEASE版本

你可能感兴趣的:(Spring)