如下图所示,左侧是三种类型的 Context:
-
XML 配置方式的 Context;
-
Spring Boot 的 Context;
-
Web 服务的 Context。
不论哪种 Context,创建后都会调用到 AbstractApplicationContext 类的 refresh 方法,流程如下。
-
首先对刷新进行准备,包括设置开始时间、设置激活状态、初始化 Context 环境中的占位符,这个动作根据子类的需求由子类来执行,然后验证是否缺失必要的 properties。
-
刷新并获得内部的 Bean Factory。
-
对 BeanFactory 进行准备工作,比如设置类加载器和后置处理器、配置不进行自动装配的类型、注册默认的环境 Bean。
-
为 Context 的子类提供后置处理 BeanFactory 的扩展能力。如果子类想在 Bean 定义加载完成后,开始初始化上下文之前做一些特殊逻辑,可以复写这个方法。
-
执行 Context 中注册的 Bean Factory 后缀处理器。这里有两种后置处理器,一种是可以注册 Bean 的后缀处理器,另一种是针对 BeanFactory 进行处理的后置处理器。执行的顺序是,先按优先级执行可注册 Bean 的处理器,在按优先级执行针对 BeanFactory的处理器。对 Spring Boot 来说,这一步会进行注解 Bean Definition 的解析。流程如图右侧所示,由 ConfigurationClassPostProcessor 触发、由 ClassPathBeanDefinitionScanner 解析并注册到 BeanFactory。
-
按优先级顺序在 BeanFactory 中注册 Bean的后缀处理器,Bean 后置处理器可以在 Bean 初始化前、后执行处理。
-
初始化消息源,消息源用来支持消息的国际化。
-
初始化应用事件广播器。事件广播器用来向 ApplicationListener 通知各种应用产生的事件,是一个标准的观察者模式。
-
是留给子类的扩展步骤,用来让特定的 Context 子类初始化其他的 Bean。
-
把实现了 ApplicationListener 的 Bean 注册到事件广播器,并对广播器中的早期未广播事件进行通知。
-
冻结所有 Bean 描述信息的修改,实例化非延迟加载的单例 Bean。
-
完成上下文的刷新工作,调用 LifecycleProcessor 的 onFresh() 方法以及发布 ContextRefreshedEvent 事件。
-
在 finally 中,执行第十三步,重置公共的缓存,比如 ReflectionUtils 中的缓存、 AnnotationUtils 中的缓存等等;
至此,Spring 的 Context 初始化完成。由于篇幅和时间的关系,这里介绍了最主要的主流程,建议课后阅读源码来复习这个知识点,补全细节。
内容来自:https://kaiwu.lagou.com/course/courseInfo.htm?courseId=1#/content