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<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

   Set<String> processedBeans = new HashSet<>();

//首先调用BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
   if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
      List<BeanDefinitionRegistryPostProcessor> 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<BeanDefinitionRegistryPostProcessor> 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<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);
      }
   }

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

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

   // 最后, 调用所有其他的BeanFactoryPostProcessors.
   List<BeanFactoryPostProcessor> 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版本

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessorSpring 框架中用于对 BeanFactoryBeanDefinition 进行后置处理的接口。它们之间有一些区别和联系。 区别: 1. 触发时机不同:BeanFactoryPostProcessorBeanFactory 标准初始化之后,所有的 bean 定义已经加载到容器中,是还没有实例化 bean。而 BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor 之前触发,用于处理 bean 的定义信息。 2. 处理的对象不同:BeanFactoryPostProcessor 主要用于对已经加载的 BeanFactory 进行后置处理,例如修改 bean 的定义、添加新的 bean 定义等。而 BeanDefinitionRegistryPostProcessor 则是在 BeanFactoryPostProcessor 之前对 BeanDefinition 进行操作,可以注册新的 bean 定义、修改已有的 bean 定义等。 联系: 1. 都可以用于修改或扩展应用程序上下文中的 bean 定义,从而影响 bean 的创建和配置。 2. 都可以通过实现相应的接口来实现自定义的后置处理逻辑。 3. BeanDefinitionRegistryPostProcessor 继承自 BeanFactoryPostProcessor 接口,因此 BeanDefinitionRegistryPostProcessor 可以同时执行 BeanFactoryPostProcessor 的功能。 总结起来,BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor 都是用于对 bean 定义和 bean 工厂进行后置处理的接口,不同的是它们触发的时机和处理的对象不同。BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor 之前触发,用于处理 bean 的定义信息,而 BeanFactoryPostProcessorBeanFactory 标准初始化之后触发,用于处理已经加载的 BeanFactory

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值