关于ApplicationContext的启动流程详解

 更新时间:2025年03月10日 08:39:30   作者:冰糖心书房  
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 (例如,ApplicationContextAwareProcessorApplicationListenerDetector 等)。
  • 配置依赖关系解析(忽略某些接口的自动装配,注册特殊的依赖项)。
  • 注册一些内置的 Bean (例如,environmentsystemPropertiessystemEnvironment)。

4. postProcessBeanFactory(beanFactory)

- BeanFactory 后置处理:

  • 允许子类对 BeanFactory 进行进一步的定制。
  • 这是一个模板方法,由具体的 ApplicationContext 实现类(如 AnnotationConfigApplicationContext)提供具体实现。

5. invokeBeanFactoryPostProcessors(beanFactory)

- 调用 BeanFactoryPostProcessor:

  • 调用所有已注册的 BeanFactoryPostProcessor (包括 BeanDefinitionRegistryPostProcessor)。
    • 先调用实现了 PriorityOrdered 接口的。
    • 再调用实现了 Ordered 接口的。
    • 最后调用普通的 BeanFactoryPostProcessor
  • BeanFactoryPostProcessor 可以在 Bean 实例化之前修改 BeanFactory 的配置元数据。
  • BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor的子接口,它可以在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。
  • 调用 LifecycleProcessoronRefresh() 方法。
  • 发布 ContextRefreshedEvent 事件,通知所有监听器容器已刷新。
  • 注册 LiveBeansView MBean (如果启用).

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 的创建和配置,但其核心启动流程仍然遵循上述步骤。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

最新评论