Spring5源码 - 04 invokeBeanFactoryPostProcessors 源码解读_1
文章目录
- Pre
- refresh()
- Spring的设计
- 源码验证
Pre
接上文 Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析
refresh()
这里我们只粗略的看一下其中的逻辑,真的很复杂
@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");// Prepare this context for refreshing. 1:准备刷新上下文环境 prepareRefresh();// Tell the subclass to refresh the internal bean factory. 2:获取告诉子类初始化Bean工厂ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context. 3:对bean工厂进行填充属性prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses. 第四:留给子类去实现该接口postProcessBeanFactory(beanFactory);StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");// Invoke factory processors registered as beans in the context. 调用bean工厂的后置处理器.invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation. 调用bean的后置处理器registerBeanPostProcessors(beanFactory);beanPostProcess.end();// Initialize message source for this context. 初始化国际化资源处理器. initMessageSource();// Initialize event multicaster for this context. 创建事件多播器initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses. 这个方法同样也是留给子类实现的 springboot也是从这个方法进行启动tomat的.onRefresh();// Check for listener beans and register them. 把我们的事件监听器注册到多播器上registerListeners();// Instantiate all remaining (non-lazy-init) singletons. 实例化我们剩余的单实例bean.finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event. 最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的)finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();contextRefresh.end();}}}
Spring的设计
我们接着来看 spring 是在哪一个方法调用中完成扫描的 即什么时候初始化BeanDefinition, 并且把这个BeanDefinition放到bdMap集合中。
通过debug分析可以得出
invokeBeanFactoryPostProcessors(beanFactory);
主要工作
执行所有的需要被执行的BeanFactoryPostProcessor
1.1 执行Spring内置的BeanFactoryPostProcessor (完成Bean的扫描) 【其实就是ConfigurationClassPostProcessor】
1.2 执行开发人员提供的BeanFactoryPostProcessor
源码验证
再细说一下主要的设计思想
看方法名 invokeBeanFactoryPostProcessors 也能猜到 主要是执行 BeanFactoryPostProcessors
既然是 BeanFactoryPostProcessors , 那就说明有很多 BeanFactoryPostProcessor
BeanFactoryPostProcessor是个接口,spring实现了一部分,当然开发人员也可以实现BeanFactoryPostProcessor接口。
那Spring该如何决定这些接口实现类的先后顺序呢? 这就是Spring IOC 核心的地方。
先说说Spring的几个比较核心的子类和实现类
主要干的两个活
- 执行直接实现了BeanFactoryPostProcessor
- 执行实现了BeanDefinitionRegistryPostProcessor
举个例子 ,假设我们有个自己的类 ,实现了 子类BeanDefinitionRegistryPostProcessor接口
ArtisanTest02 implements BeanDefinitionRegistryPostProcessor
那么你不仅要把BeanDefinitionRegistryPostProcessor的接口实现,还要实现其父类BeanFactoryPostProcessor接口的方法,那么在调用invokeBeanFactoryPostProcessors的时候 ,这两个方法都会被执行 。
假设还有一个类 ,ArtisanTest03 实现了 BeanFactoryPostProcessor 接口
ArtisanTest03 implements BeanFactoryPostProcessor
来运行看下效果
Spring5源码 - 04 invokeBeanFactoryPostProcessors 源码解读_1相关推荐
- Spring5源码 - 05 invokeBeanFactoryPostProcessors 源码解读_3细说invokeBeanDefinitionRegistryPostProcessors
文章目录 Pre 细说invokeBeanDefinitionRegistryPostProcessors 流程图 源码分析 解析配置类 parser.parse(candidates) 配置类注册到 ...
- Spring5源码 - 05 invokeBeanFactoryPostProcessors 源码解读_2
文章目录 Pre 源码解读 总体流程 源码分析 细节解析 [初始化对应的集合 & 遍历用户自己手动添加的后置处理器] [调用实现了PriorityOrdered接口的BeanDefinitio ...
- ubuntu安装python_ubuntu18.04下源码编译安装最新版本Python3
原文链接:ubuntu18.04下源码编译安装最新版本Python3 截止到2019年4月9日,Python3最新的版本是3.7.3. 在ubuntu18.04中已经安装的Python3版本是3.6. ...
- 【ElasticSearch】Es 源码之 CcrRestoreSourceService 源码解读
文章目录 1.概述 2.构造方法 1.概述 在博客 [ElasticSearch]Es 源码之 LifecycleComponent 源码解读 中初始化了相关插件的CcrRestoreSourceSe ...
- 【ElasticSearch】Es 源码之 AutoFollowCoordinator 源码解读
文章目录 1.概述 2.构造方法 3. start方法 1.概述 在博客 [ElasticSearch]Es 源码之 LifecycleComponent 源码解读 中初始化了相关插件的AutoFol ...
- 【ElasticSearch】Es 源码之 CleanerService 源码解读
文章目录 1.概述 2.构造方法 1.概述 在博客 [ElasticSearch]Es 源码之 LifecycleComponent 源码解读 中初始化了相关插件的CleanerService ,其中 ...
- 【ElasticSearch】Es 源码之 Exporters 源码解读
文章目录 1.概述 2.start 2.1 initExporters 1.概述 在博客 [ElasticSearch]Es 源码之 LifecycleComponent 源码解读 中初始化了相关插件 ...
- 【ElasticSearch】Es 源码之 CacheService 源码解读
文章目录 1.概述 1.概述 在博客 [ElasticSearch]Es 源码之 LifecycleComponent 源码解读 中初始化了相关插件的LifecycleComponent ,其中初始化 ...
- 【ElasticSearch】Es 源码之 AsyncSearchMaintenanceService 源码解读
文章目录 1.概述 1.概述 在博客 [ElasticSearch]Es 源码之 LifecycleComponent 源码解读 中初始化了相关插件的LifecycleComponent ,其中初始化 ...
最新文章
- Linux 问题解决 :/lib/systemd/systemd-journald 占用内存过高
- 通过案例学调优之--AWR baseline对比生成AWR报告
- 数组的reduce方法
- parted--大于2T的分区工具
- c++17(2)-枚举类enum class
- 深入了解EntityFramework——Lazy Loading与Eager Loading
- Resharper进阶一:简要介绍
- 写作新手想少走弯路,尽快赚到钱,必须要知道的
- GoWeb开发_Iris框架讲解(二):Get、Post、Put等请求及数据返回格式
- <树莓派>——无法向U盘写入文件
- 基于A*启发式搜索解决迷宫问题
- deecamp训练营
- macOS 访达的隐藏小技巧
- 【小程序】小程序里跳转网页链接
- iPhone 屏幕尺寸
- 【美团 技术篇】美团推荐算法实践
- php wordpress 代码模板,wordpress模板代码详解
- 客制化键盘编程_客制化键盘QMK固件入门-修改keyboard和keymap
- 校园失物招领系统,失物招领系统,校园失物招领管理系统毕设作品
- oracle 与赛门铁克,Oracle与赛门铁克认证Veritas数据中心解决方案
热门文章
- android edittext 联想,Android 输入法联想问题
- C++ >>和<<读写文本文件
- sql 精读(六)获取每个类别中最受欢迎的商品
- 链表c的经典实现(一)
- 计算机专业的金书,《计算机专业英语》书评,金书网
- vb表格控件_(超级干货)ExcelVBA拆分表格并分别发送邮件增强版
- vue 改变domclass_基于 vue 开发甘特图组件的心路历程(兼设计分享)
- 文巾解题 53. 最大子序和
- python怎么打开ipynb文件_如何优雅的打开.ipynb文件
- tensorflow2中如何设置GPU的使用