关于ApplicationContext的启动流程详解
作者:冰糖心书房
ApplicationContext是Spring框架中用于管理和配置Bean的核心接口,它的启动流程包括准备刷新、获取BeanFactory、准备BeanFactory、后置处理BeanFactory、调用BeanFactoryPostProcessor、注册BeanPostProcessor
ApplicationContext的启动流程
ApplicationContext是 Spring IoC 容器的核心接口,它提供了配置、访问和管理 Bean 的功能。ApplicationContext的启动流程可以细分为以下几个关键步骤,这些步骤主要在AbstractApplicationContext类的refresh()方法中实现:
1. prepareRefresh()
- 准备刷新:
- 设置启动时间戳。
- 设置容器的激活状态。
- 初始化属性源 (property sources),用于解析占位符(例如,
${...})。 - 验证必需的属性(如果有)。
- 创建并保存早期事件监听器集合 (early application listeners).
2. obtainFreshBeanFactory()
- 获取 BeanFactory:
- 如果存在旧的
BeanFactory,则销毁其中的 Bean 并关闭旧的BeanFactory。 - 创建新的
BeanFactory(通常是DefaultListableBeanFactory)。 - 设置
BeanFactory的序列化 ID (如果需要)。 - 定制
BeanFactory(例如,设置类加载器、添加后置处理器等)。 - 加载 Bean 定义 (调用
loadBeanDefinitions方法):XmlBeanDefinitionReader: 从 XML 配置文件加载。AnnotatedBeanDefinitionReader: 从注解配置类加载。ClassPathBeanDefinitionScanner: 扫描类路径并加载带有注解的 Bean。
3. prepareBeanFactory(beanFactory)
- 准备 BeanFactory:
- 设置
BeanFactory的类加载器。 - 设置表达式解析器 (用于解析 SpEL 表达式)。
- 设置属性编辑器注册器。
- 添加内置的
BeanPostProcessor(例如,ApplicationContextAwareProcessor、ApplicationListenerDetector等)。 - 配置依赖关系解析(忽略某些接口的自动装配,注册特殊的依赖项)。
- 注册一些内置的 Bean (例如,
environment、systemProperties、systemEnvironment)。
4. postProcessBeanFactory(beanFactory)
- BeanFactory 后置处理:
- 允许子类对
BeanFactory进行进一步的定制。 - 这是一个模板方法,由具体的
ApplicationContext实现类(如AnnotationConfigApplicationContext)提供具体实现。
5. invokeBeanFactoryPostProcessors(beanFactory)
- 调用 BeanFactoryPostProcessor:
- 调用所有已注册的
BeanFactoryPostProcessor(包括BeanDefinitionRegistryPostProcessor)。- 先调用实现了
PriorityOrdered接口的。 - 再调用实现了
Ordered接口的。 - 最后调用普通的
BeanFactoryPostProcessor。
- 先调用实现了
BeanFactoryPostProcessor可以在 Bean 实例化之前修改 BeanFactory 的配置元数据。BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,它可以在Bean 定义加载完成后,但在 Bean 实例化之前执行,允许添加、删除或修改 Bean 定义。
6. registerBeanPostProcessors(beanFactory)
- 注册 BeanPostProcessor:
- 注册所有实现了
BeanPostProcessor接口的 Bean。- 先注册实现了
PriorityOrdered接口的。 - 再注册实现了
Ordered接口的。 - 最后注册普通的
BeanPostProcessor。 - 重新注册内部的
BeanPostProcessor(MergedBeanDefinitionPostProcessor).
- 先注册实现了
BeanPostProcessor可以在 Bean 初始化前后进行处理。
7. initMessageSource()
- 初始化 MessageSource:
- 初始化国际化消息源 (
MessageSource)。 - 如果在
BeanFactory中找到名为messageSource的 Bean,则使用该 Bean;否则,创建一个默认的DelegatingMessageSource。
8. initApplicationEventMulticaster() - 初始化事件广播器:
- 初始化应用事件广播器 (
ApplicationEventMulticaster)。 - 如果在
BeanFactory中找到名为applicationEventMulticaster的 Bean,则使用该 Bean;否则,创建一个默认的SimpleApplicationEventMulticaster。
9. onRefresh()
- 刷新 (可选):
- 这是一个模板方法,由具体的
ApplicationContext实现类提供具体实现。 - 例如,
AbstractRefreshableWebApplicationContext会在这里创建或刷新 Servlet 上下文。
10. registerListeners()
- 注册监听器:
- 将之前收集的早期应用事件监听器 (early application listeners) 和在容器中定义的监听器注册到事件广播器 (
ApplicationEventMulticaster)。 - 发布早期的应用事件 (early application events).
11. finishBeanFactoryInitialization(beanFactory)
- 完成 BeanFactory 初始化:
- 初始化类型转换器 (
ConversionService),如果存在名为conversionService的 Bean。 - 冻结配置(不允许再修改 Bean 定义)。
- 实例化所有剩余的非懒加载的单例 Bean (调用
beanFactory.preInstantiateSingletons())。
12. finishRefresh()
- 完成刷新:
- 清空资源缓存 (例如,
ResourceBundleMessageSource的缓存)。 - 初始化生命周期处理器 (
LifecycleProcessor),如果存在名为lifecycleProcessor的 Bean。 - 调用
LifecycleProcessor的onRefresh()方法。 - 发布
ContextRefreshedEvent事件,通知所有监听器容器已刷新。 - 注册
LiveBeansViewMBean (如果启用).
13. 异常处理和重置
- 如果在
refresh()过程中发生异常, 则销毁已经创建的单例 Bean. - 重置容器的激活状态.
总结流程图:
+-----------------------+
| start() |
+-----------------------+
|
V
+-----------------------+
| refresh() |
+-----------------------+
|
V
+-----------------------+
| prepareRefresh() | (准备刷新)
+-----------------------+
|
V
+-----------------------+
| obtainFreshBeanFactory()| (获取 BeanFactory, 加载 Bean 定义)
+-----------------------+
|
V
+-----------------------+
| prepareBeanFactory() | (准备 BeanFactory)
+-----------------------+
|
V
+-----------------------+
|postProcessBeanFactory()| (BeanFactory 后置处理, 可选)
+-----------------------+
|
V
+-----------------------+
|invokeBeanFactoryPPs()| (调用 BeanFactoryPostProcessor)
+-----------------------+
|
V
+-----------------------+
|registerBeanPostPrcs()| (注册 BeanPostProcessor)
+-----------------------+
|
V
+-----------------------+
| initMessageSource() | (初始化 MessageSource)
+-----------------------+
|
V
+-----------------------+
|initApplicationEventM()| (初始化事件广播器)
+-----------------------+
|
V
+-----------------------+
| onRefresh() | (刷新, 可选)
+-----------------------+
|
V
+-----------------------+
| registerListeners() | (注册监听器)
+-----------------------+
|
V
+-----------------------+
|finishBeanFactoryInit()| (完成 BeanFactory 初始化, 实例化单例 Bean)
+-----------------------+
|
V
+-----------------------+
| finishRefresh() | (完成刷新, 发布 ContextRefreshedEvent)
+-----------------------+
|
V
+-----------------------+
| 容器就绪 |
+-----------------------+关键点:
refresh()方法是ApplicationContext启动的核心。BeanFactory是实际创建和管理 Bean 的组件。BeanDefinition描述了如何创建和配置 Bean。BeanFactoryPostProcessor可以在 Bean 实例化之前修改 BeanFactory 的配置元数据。BeanPostProcessor可以在 Bean 初始化前后进行处理。ApplicationListener可以监听容器发布的事件。- Spring Boot 在 Spring Framework 的基础上,进一步简化了
ApplicationContext的创建和配置,但其核心启动流程仍然遵循上述步骤。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
