参考源

https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click

https://www.bilibili.com/video/BV12Z4y197MU?spm_id_from=333.999.0.0

《Spring源码深度解析(第2版)》

版本

本文章基于 Spring 5.3.15


Spring IOC 的核心是 AbstractApplicationContextrefresh 方法。

其中一共有 13 个主要方法,这里分析第 6 个:registerBeanPostProcessors

1 AbstractApplicationContext

1-1 注册 Bean 增强器

registerBeanPostProcessors(beanFactory)
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 注册 Bean 增强器
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

1-2 注册 Bean 增强器

PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this)

2 PostProcessorRegistrationDelegate

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<>();
// 使用 Ordered 保证顺序
List<String> orderedPostProcessorNames = new ArrayList<>();
// 无序 BeanPostProcessor
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);
// 注册 Bean 增强器
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 探测器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

2-1 排序增强器

sortPostProcessors(priorityOrderedPostProcessors, beanFactory)
private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
if (postProcessors.size() <= 1) {
return;
}
Comparator<Object> comparatorToUse = null;
if (beanFactory instanceof DefaultListableBeanFactory) {
comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
}
if (comparatorToUse == null) {
comparatorToUse = OrderComparator.INSTANCE;
}
postProcessors.sort(comparatorToUse);
}

2-2 注册 Bean 增强器

registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors)
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) { if (beanFactory instanceof AbstractBeanFactory) {
// Bulk addition is more efficient against our CopyOnWriteArrayList there
((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors);
}
else {
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
}

Spring源码 11 IOC refresh方法6的更多相关文章

  1. Spring源码 16 IOC refresh方法11

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  2. Spring源码 18 IOC refresh方法13

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  3. Spring源码 17 IOC refresh方法12

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  4. Spring源码 15 IOC refresh方法10

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  5. Spring源码 14 IOC refresh方法9

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  6. Spring源码 09 IOC refresh方法4

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  7. Spring源码 08 IOC refresh方法3

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  8. Spring源码 07 IOC refresh方法2

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  9. Spring源码 06 IOC refresh方法1

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

随机推荐

  1. 云开发中的战斗机 Laf,让你像写博客一样写代码

    各位云原生搬砖师 and PPT 架构师,你们有没有想过像写文章一样方便地写代码呢? 怎样才能像写文章一样写代码? 理想的需求应该是可以在线编写.调试函数,不用重启服务,随时随地在 Web 上查看函数 ...

  2. Kubernetes Job Controller 原理和源码分析(二)

    概述程序入口Job controller 的创建Controller 对象NewController()podControlEventHandlerJob AddFunc DeleteFuncJob ...

  3. 接口测试postman深度挖掘应用②

    上一篇文章我们已经介绍了postman的基本用法,以及接口测试原理.未关注博主的可以关注下博主,后期测试安全,以及各种工具用法,编程语言都会有讲解的 老样子:①先补习基础知识:  ②补充上一章节由于过 ...

  4. 2020.10.24【普及组】模拟赛C组 总结

    T1:暴力 1:先从 6 个中选三个,再把选出的三个全排列,全排列后再判断是否可行 2:把 6 个全都全排列,然后判断 T2:判断误差 1:减法时结果加上 1e-8 2:把小数乘上 1e6 左右 考试 ...

  5. 前端学习 linux —— 第一篇

    前端学习 linux - 第一篇 本文主要介绍"linux 发行版本"."cpu 架构"."Linux 目录结构"."vi 和 v ...

  6. ElasticSearch7.3学习(三十二)----logstash三大插件(input、filter、output)及其综合示例

    1. Logstash输入插件 1.1 input介绍 logstash支持很多数据源,比如说file,http,jdbc,s3等等 图片上面只是一少部分.详情见网址:https://www.elas ...

  7. 自定义监控lvs

    1. 修改zabbix_agent配置文件添加以下内容,重启agent Include=/etc/zabbix/zabbix_agentd.d/ 2. 在zabbix安装目录下的scripts目录下添 ...

  8. RPA应用场景-银行回单查询

    场景概述银行回单查询 所涉系统名称银行网银 人工操作(时间/次) 5 分钟 所涉人工数量 4 操作频率不定时 场景流程 1.收到外派业务员申请查询收入银行回单的邮件: 2.依据邮件中提供的客户信息进入 ...

  9. 一个紧张刺激的聊天器,要不要进来看看(Python UDP网络模型)

    先来哔哔两句:(https://jq.qq.com/?_wv=1027&k=QgGWqAVF) 互联网的本质是什么?其实就是信息的交换.那么如何将自己的信息发送到其他人的电脑上呢?那就需要借助 ...

  10. Electron学习(三)之简单交互操作

    写在前面 最近一直在做批量测试工具的开发,打包的exe,执行也是一个黑乎乎的dos窗口,真的丑死了,总感觉没个界面,体验不好,所以就想尝试写桌面应用程序. 在技术选型时,Java窗体实现使用JavaF ...