IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> spring ioc容器创建过程(3)registerBeanPostProcessors -> 正文阅读

[Java知识库]spring ioc容器创建过程(3)registerBeanPostProcessors

一、前文回顾

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)

public static void registerBeanPostProcessors(
      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(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
   //使用PriorityOrdered 保证顺序
   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
         priorityOrderedPostProcessors.add(pp);
         if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
         }
      } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      } else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }
   //第1 步,注册所有实现PriorityOrdered 的BeanPostProcessor
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
   //第2步, 注册所有实现Ordered 的BeanPostProcessor
   List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
   for (String ppName : orderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);
   //第3 步,注册所有无序的BeanPostProcessor
   List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
   for (String ppName : nonOrderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
   //第4 步, 注册所有MergedBeanDefinitionPostProcessor 类型的BeanPostProcessor ,并非
   //重复注册,在beanFactory.addBeanPostProcessor 中会先移除已经存在的BeanPostProcessor
   sortPostProcessors(internalPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, internalPostProcessors);
   //添加ApplicationListener 探测器
    // 把ApplicationListenerDetector 移动到最后
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
总体来说就是获取到了BeanFactory中定义的所有的BeanPostProcessor对象,并添加到AbstractBeanFactory中的beanPostProcessors数组中,以便后面创建bean的时候进行调用/

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

3.2、registerBeanPostProcessors

private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
        Iterator var2 = postProcessors.iterator();
        while(var2.hasNext()) {
            BeanPostProcessor postProcessor = (BeanPostProcessor)var2.next();
            beanFactory.addBeanPostProcessor(postProcessor);
        }
    }
    public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
        this.beanPostProcessors.remove(beanPostProcessor);
        this.beanPostProcessors.add(beanPostProcessor);
        if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
            this.hasInstantiationAwareBeanPostProcessors = true;
        }
        if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
            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 完全初始化,放置最后比较合适。
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-08-02 20:46:54  更:2021-08-02 20:47:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/3 13:26:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码