spring ioc容器创建过程(3)registerBeanPostProcessors

2022-10-02 07:57:27

一、前文回顾

spring ioc容器创建过程(1)BeanFactory的创建
spring ioc容器创建过程(2)invokeBeanFactoryPostProcessors

二、BeanPostProcessor

BeanPostProcessor 提供Spring Bean 初始化前和初始化后的生命周期回调,分别对应postProcessBeforeInitialization 以及 postProcessAfterInitialization 方法,允许对关心的Bean 进行扩展 ,甚至是替换。
举个例子:

  1. ApplicationContext 相关的Aware 回调也是基于 BeanPostProcessor 实现,即ApplicationContextAwareProcessor;
  2. BeanFactoryPostProcessor 是Spring BeanFactory(实际为 ConfigurableListableBeanFactory)的后置处理器,用于扩展 BeanFactory,或通过BeanFactory 进行依赖查找和依赖注入。

但是值得注意的是BeanFactoryPostProcessor 必须要有Spring ApplicationContext 的创建,BeanFactory 无法与其直接进行交互。 而BeanPostProcessor 则直接与BeanFactory 关联,属于N 对1 的关系。

三、BeanFactory注册BeanPostProcessor阶段

3.1、AbstractApplicationContext#registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory)

publicstaticvoidregisterBeanPostProcessors(ConfigurableListableBeanFactory beanFactory,AbstractApplicationContext applicationContext){String[] postProcessorNames= beanFactory.getBeanNamesForType(BeanPostProcessor.class,true,false);/*
      BeanPostProcessorChecker 是一个普通的信息打印,可能会有些情况,
      当Spring 的配置中的后处理器还没有被注册就已经开始了bean 的初始化时
      便会打印出 BeanPostProcessorChecker 中设定的信息
   */int beanProcessorTargetCount= beanFactory.getBeanPostProcessorCount()+1+ postProcessorNames.length;
   beanFactory.addBeanPostProcessor(newBeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));//使用PriorityOrdered 保证顺序List<BeanPostProcessor> priorityOrderedPostProcessors=newArrayList<>();List<BeanPostProcessor> internalPostProcessors=newArrayList<>();List<String> orderedPostProcessorNames=newArrayList<>();List<String> nonOrderedPostProcessorNames=newArrayList<>();for(String ppName: postProcessorNames){if(beanFactory.isTypeMatch(ppName,PriorityOrdered.class)){BeanPostProcessor pp= beanFactory.getBean(ppName,BeanPostProcessor.class);
         priorityOrderedPostProcessors.add(pp);if(ppinstanceofMergedBeanDefinitionPostProcessor){
            internalPostProcessors.add(pp);}}elseif(beanFactory.isTypeMatch(ppName,Ordered.class)){
         orderedPostProcessorNames.add(ppName);}else{
         nonOrderedPostProcessorNames.add(ppName);}}//第1 步,注册所有实现PriorityOrdered 的BeanPostProcessorsortPostProcessors(priorityOrderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);//第2步, 注册所有实现Ordered 的BeanPostProcessorList<BeanPostProcessor> orderedPostProcessors=newArrayList<>(orderedPostProcessorNames.size());for(String ppName: orderedPostProcessorNames){BeanPostProcessor pp= beanFactory.getBean(ppName,BeanPostProcessor.class);
      orderedPostProcessors.add(pp);if(ppinstanceofMergedBeanDefinitionPostProcessor){
         internalPostProcessors.add(pp);}}sortPostProcessors(orderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, orderedPostProcessors);//第3 步,注册所有无序的BeanPostProcessorList<BeanPostProcessor> nonOrderedPostProcessors=newArrayList<>(nonOrderedPostProcessorNames.size());for(String ppName: nonOrderedPostProcessorNames){BeanPostProcessor pp= beanFactory.getBean(ppName,BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);if(ppinstanceofMergedBeanDefinitionPostProcessor){
         internalPostProcessors.add(pp);}}registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);//第4 步, 注册所有MergedBeanDefinitionPostProcessor 类型的BeanPostProcessor ,并非//重复注册,在beanFactory.addBeanPostProcessor 中会先移除已经存在的BeanPostProcessorsortPostProcessors(internalPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, internalPostProcessors);//添加ApplicationListener 探测器// 把ApplicationListenerDetector 移动到最后
   beanFactory.addBeanPostProcessor(newApplicationListenerDetector(applicationContext));}
总体来说就是获取到了BeanFactory中定义的所有的BeanPostProcessor对象,并添加到AbstractBeanFactory中的beanPostProcessors数组中,以便后面创建bean的时候进行调用/

结合上一篇文章的描述,可以发现BeanPostProcessor 的处理与BeanFactoryPostProcessor 的处理极为相似,但是似乎又有些不一样的地方。经过反复的对比发现,对于BeanFactoryPostProcessor的处理要区分两种情况, 一种方式是通过硬编码方式的处理, 另一种是通过配置文件方式的处理。那么为什么在BeanPostProcessor 的处理中只考虑了配置文件的方式而不考虑硬编码的方式呢?对于BeanFactoryPostProcessor的处理,不但要实现注册功能,而且还要实现对后处理器的激活操作,所以需要载入配置中的定义,并进行激活;而对于BeanPostProcessor 并不需要马上调用,再说,硬编码的方式实现的功能是将后处理器提取并调用,这里并不需要调用,当然不需要考虑硬编码的方式了,这里的功能只需要将配置文件的BeanPostProcessor 提取出来并注册进入beanFactory 就可以了。对于beanFactory 的注册,也不是直接注册就可以的。在Spring 中支持对于BeanPostProcessor的排序, 比如根据PriorityOrdered 进行排序、根据Ordered 进行排序或者无序,而Spring
在BeanPostProcessor 的激活顺序的时候也会考虑对于顺序的问题而先进行排序。

3.2、registerBeanPostProcessors

privatestaticvoidregisterBeanPostProcessors(ConfigurableListableBeanFactory beanFactory,List<BeanPostProcessor> postProcessors){Iterator var2= postProcessors.iterator();while(var2.hasNext()){BeanPostProcessor postProcessor=(BeanPostProcessor)var2.next();
            beanFactory.addBeanPostProcessor(postProcessor);}}publicvoidaddBeanPostProcessor(BeanPostProcessor beanPostProcessor){Assert.notNull(beanPostProcessor,"BeanPostProcessor must not be null");this.beanPostProcessors.remove(beanPostProcessor);this.beanPostProcessors.add(beanPostProcessor);if(beanPostProcessorinstanceofInstantiationAwareBeanPostProcessor){this.hasInstantiationAwareBeanPostProcessors=true;}if(beanPostProcessorinstanceofDestructionAwareBeanPostProcessor){this.hasDestructionAwareBeanPostProcessors=true;}}

在registerBeanPostProcessors 方法的实现中确保了beanPostProcessor的唯一性,个人猜想,之所以选择在registerBeanPostProcessors 中没有进行重复移除操作或许是为了保持分类的效果,使逻辑更为清晰吧。

四、总结

AbstractApplicationContext#registerBeanPostProcessors(ConfigurableListableBeanFactory) 方法,主要初始化 BeanPostProcessor 类型的 Bean(依赖查找),会做以下事情:

  1. 获取所有 BeanPostProcessor 类型的 beanName
  2. 添加 BeanPostProcessor - BeanPostProcessorChecker,用于打印日志(所有 BeanPostProcessor 还没有全部实例化就有 Bean 初始化完成)
  3. 获取所有 BeanPostProcessor 实现类(依赖查找),添加至 BeanFactory 容器中(顺序:PriorityOrdered > Ordered > 无)
  4. 注意,第3 步添加的 BeanPostProcessor 如果是 MergedBeanDefinitionPostProcessor 类型,会再次添加(先移除在添加,也就是将顺序往后挪)
  5. 重新添加 BeanPostProcessor - ApplicationListenerDetector,目的将其移至最后,因为这个后置处理器用于探测 ApplicationListener 类型的 Bean,需要保证 Bean 完全初始化,放置最后比较合适。
  • 作者:十元里
  • 原文链接:https://blog.csdn.net/lisyee/article/details/119305380
    更新时间:2022-10-02 07:57:27