总文档 :文章目录
Github : github.com/black-ant
一 . 前言
这一篇来详细看看 ApplicationContext 的整体逻辑 , ApplicationContext 整个逻辑中最重要的的一环 , 他具有以下的作用 :
- 从ListableBeanFactory继承了用于访问应用程序组件的Bean工厂方法的能力
- 从ResourceLoader接口继承了以通用方式加载文件资源的能力
- 从ApplicationEventPublisher接口继承了向注册监听器发布事件的能力。
- 从MessageSource接口继承了解析消息的能力,支持国际化。
- 单个父上下文可以被整个web应用程序使用,而每个servlet有它自己的独立于任何其他servlet的子上下文。
- 标准的BeanFactory生命周期功能之外
- 支持检测和调用ApplicationContextAware以及ResourceLoaderAware , ApplicationEventPublisherAware和MessageSourceAware
看一下整体的逻辑
二 . ApplicationContext 的初始化
容器的初始化主要是 ApplicationContextInitializer , 我们先看一下他的家族体系
容器初始化的起点
ApplicationContextInitializer 内部只有一个方法
1 | java复制代码I- ApplicationContextInitializer |
我们要看的主要 C- SpringApplication , 先看看主方法 , 其中run 方法中处理 Context 的有几个地方
1 | java复制代码public ConfigurableApplicationContext run(String... args) { |
一个个看这几个节点
Step 1 : 创建容器
1 | java复制代码C01- SpringApplication |
PS: 通常如果我们使用 SpringMVC , 创建的一般是 AnnotationConfigServletWebServerApplicationContext
1 | JAVA复制代码C01- SpringApplication |
伪代码 —->
1 | java复制代码// M1_35 核心代码 |
整个代码的核心就在于 applyInitializers :
1 | java复制代码// M1_37 伪代码 |
可以看到 , 这里 For 循环执行了很多 ApplicationContextInitializer 类 ,他们分别为容器配置了相关的属性
相关处理
1 | java复制代码C07- DelegatingApplicationContextInitializer |
额外操作 ComponentScanPackageCheck
1 | java复制代码C- ComponentScanPackageCheck |
三 . ApplicationContext 的业务逻辑
上面看完了 ApplicationContext 的初始化逻辑 , 下面看一下业务逻辑
业务处理的核心在于类AbstractApplicationContext , SpringBoot 启动时 , 会在该类中处理部分 Context 的逻辑
1 | java复制代码C50- AbstractApplicationContext |
我们依次来看一下相关的方法功能 :
Module 1 : 标识属性的作用 , 我们常用的属性通常Id 和 Environment
1 | java复制代码M- void setId(String id) |
Module 2 : 事件的发布
1 | java复制代码M- void publishEvent(ApplicationEvent event) |
Module 3 : 主要的get方法
1 | java复制代码M- ApplicationEventMulticaster getApplicationEventMulticaster() : 获取多播器 |
Module 4 : 初始化操作
1 | java复制代码M50_20- void initMessageSource() : 初始化MessageSource |
Module 5 : 主要操作
1 | java复制代码M- void resetCommonCaches() : 重新清空缓存 |
M50_25 伪代码
1 | java复制代码protected void doClose() { |
最重要的核心逻辑系列
1 | java复制代码// 核心方法详解 |
M50_2 伪代码 , 回头继续看一下这个流程
1 | java复制代码 @Override |
BeanPostProcessors 流程比较多 , 足够开个单章了,这里就不说了
作用 : 允许对应用程序上下文的bean定义进行自定义修改 , 可以调整上下文的基础bean工厂的bean属性值
特点 : BeanFactoryPostProcessor可以与bean定义交互并修改它们,但绝不会与bean实例交互
此处主要调用 ConfigurationClassPostProcessor , 其中处理 processConfigBeanDefinitions
1 | java复制代码C52- PostProcessorRegistrationDelegate |
registerBeanPostProcessors
1 | java复制代码 |
DefaultLifecycleProcessor 流程
1 | java复制代码 |
- Lifecycle 接口 :
- 定义启动/停止生命周期控制方法的公共接口
- 可以是 Bean 和容器
- 当ApplicationContext自身启动和停止时,它将自动调用上下文内所有生命周期的实现
- LifecycleProcessor 接口 :
- LifecycleProcessor 负责管理ApplicationContext生命周期
- LifecycleProcessor自身扩展了Lifecycle接口。它也增加了两个其他的方法来与上下文交互,使得可以刷新和关闭
- LifecycleProcessor的onRefresh与onClose是比较重要的方法
- onRefresh作用是容器启动成功
- onClose是只应用要关闭的时候
- DefaultLifecycleProcessor
- 默认LifecycleProcessor实现,主要是负责所有的LifecycleProcessor实现执行
- DefaultLifecycleProcessor是LifecycleProcessor的代理对象。
M50_14 : 伪代码
1 | java复制代码protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { |
M50_16 finishBeanFactoryInitialization
1 | java复制代码M50_16- void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) |
总结
整个 ApplicationContext 流程就完成了 , 这个流程完结后 , 就可以开始 IOC Bean 的加载流程了.
写着真累 , 具体逻辑看图应该就差不多了
更新记录
- V20210803 : 优化文本错位问题
本文转载自: 掘金