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

你可能感兴趣的:(2025,Java面试系列,Spring,Framework,spring)