总文档 :文章目录
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 : 优化文本错位问题
 
本文转载自: 掘金