文章目录
- 一. 前言
- 二. 源码浅析
- 1. 入口
- 2. 执行SpringApplication的run()方法
- 2.1 获取运行监听管理器
- 2.2 环境构建
- 2.3 创建应用上下文
- 2.4 初始化应用上下文
- 2.5 刷新应用上下文
- 2.5.1 刷新前预处理
- 2.5.2 获取beanFactory
- 2.5.3 beanFactory预处理
- 2.5.4 beanFactory再次处理
- 2.5.5 调用BeanFactoryPostProcessor和其子类的后置处理方法(含解析@Configuration、@Bean等注解)
- 2.5.6 注册bean后置处理器BeanPostProcessor
- 2.5.7 初始化国际化处理器MessageSource
- 2.5.8 初始化事件广播器
- 2.5.9 为上下文设置themeSource和webServer
- 2.5.10 为上下文的事件广播器添加监听器
- 2.5.11 完成beanFactory的初始化(含实例化非惰性单例bean)
- 2.5.12 完成上下文刷新
- 2.6 应用上下文后处理
- 2.7 执行Runner, 启动就绪
- 三. 拓展
- 3.1 Environment添加PropertySource过程
- 3.1.1 执行父类AbstractEnvironment的构造器方法
- 3.1.2 执行StandardServletEnvironment的customizePropertySources方法
- 3.1.3 执行父类StandardEnvironment的customizePropertySources方法
- 3.1.4 执行ConfigurationPropertySources#attach方法
- 3.1.5 SpringCloud中存在父子容器创建过程, 父容器创建完成后, 会给子容器Environment添加一个propertySource
- 3.1.6 ConfigFileApplicationListener执行EnvironmentPostProcessor加载其余的配置文件
- 3.2 SpringCloud的父子容器
- 3.3 应用上下文
- 3.4 BeanFactoryPostProcessor与BeanPostProcessor的区别
- 四. 思考
- 五. 参考文档
一. 前言
1. 相关文章
- SpringBoot启动源码浅析 (本文)
- SpringCloud父子容器源码浅析
2. 说明
- 本文SpringBoot源码解读使用的版本为2.3.9.RELEASE. 引入依赖 spring-boot-starter-web:2.3.9.RELEASE (此版本相对3.X可读性更强, 学习源码推荐使用此版本)
- 本文会稍微提到SpringCloud, 使用的版本为 spring-cloud-context:2.2.7.RELEASE
- 本文所有内容都是基于个人理解, 有疑问时请自行研读源码
- Spring官方文档: https://spring.io/projects/spring-boot
- SpringBoot官方参考文档: https://docs.spring.io/spring-boot/docs/current/reference/html/
- 本文属性翻译中文都是瞎取名, 不要在意细节.
- 本文属性翻译中文都是瞎取名, 不要在意细节.
- 本文属性翻译中文都是瞎取名, 不要在意细节.
使用到的依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
<version>2.2.7.RELEASE</version>
</dependency>
</dependencies>
二. 源码浅析
1. 入口
1.1 启动引导类
SpringBoot的项目启动从SpringApplication的run方法开始.
@SpringBootApplication
public class StudyApplication {
public static void main(String[] args) {
// 创建SpringApplication对象. 参数为主启动类
SpringApplication springApplication = new SpringApplication(StudyApplication.class);
// 执行run方法
springApplication.run(args);
}
}
启动代码也可以写成 SpringApplication.run(StudyApplication.class, args);
1.2 创建SpringApplication
跟踪SpringApplication的构造方法进入最终的构造器中
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
// 初始化资源加载器, 默认为null
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
// 设置首要加载源. (后续本文都称sources和primarySources为加载源)
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// 推断web应用类型
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 设置初始化器
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 设置监听器. 该监听器用于监听ApplicationEvent事件
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 通过栈信息推断main方法的所在的启动类
this.mainApplicationClass = deduceMainApplicationClass();
}
构造器中做了以下几点
- 设置首要加载源(后续本文都称sources和primarySources为加载源). 加载源类作为后续应用上下文扫描加载bean的入口
- 确认web应用类型. 根据扫描reactive和servlet关联的类确认web应用类型.
- 类型一共有三种: REACTIVE、SERVLET、NONE. 本项目引用了spring-boot-starter-web故为SERVLET应用
- webApplicationType作用: 确定创建Environment的实现类型, 确认创建应用上下文的实现类型
- 设置初始化器. 默认添加的初始化器如下图,源码说明如下
- 调用getSpringFactoriesInstances方法, 传入要获取指定类型(这里为ApplicationContextInitializer)的bean集合
- 首先通过SpringFactoriesLoader#loadFactoryNames方法获取META-INF/spring.factories下所有的接口及其实现类
- 然后遍历获取指定类型(这里为ApplicationContextInitializer)的实现类名字列表, 反射创建bean, 将创建的bean加入初始化器列表
- 拓展点: 可以手动添加自己需要的初始化器监听器等到META-INF/spring.factories下
- 设置监听器. 默认添加的监听器如下图
- 加载方式: 加载监听器的方式和初始化一样, 也是调用getSpringFactoriesInstances方法
- 监听器作用: 监听器会监听ApplicationEvent方法, 处理其关注的ApplicationEvent事件
- SpringCloud相关: SpringCloud项目启动时也会添加多个监听器, 其中一个重要的监听器为BootstrapApplicationListener. 详情可查询系列文章 SpringCloud父子容器源码浅析
- SpringApplicationEvent事件类型: SpringApplicationEvent是ApplicationEvent的子类, 在SpringBoot启动中发布的SpringApplicationEvent类型如下(按照时间顺序排列):
- ApplicationStartingEvent 应用开始启动事件
- ApplicationEnvironmentPreparedEvent 环境已准备好事件
- ApplicationContextInitializedEvent 应用上下文创建并初始化完成事件
- ApplicationPreparedEvent 应用上下文准备完成事件 (应用上下文加载完,在调用refreshContext之前)
- ApplicationStartedEvent 应用程序已启动事件
- ApplicationReadyEvent 应用程序已就绪事件
- ApplicationFailedEvent 应用程序启动失败事件
- 通过栈信息推断main方法的所在的启动类(逻辑简单, 不展开)
2. 执行SpringApplication的run()方法
public ConfigurableApplicationContext run(String... args) {
// 计时器. 开始计时
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
// 设置系统属性“java.awt.headless”的值, 默认为true.用于运行headless服务器, 进行简单的图像处理(不展开)
// 多用于在缺少显示屏、键盘或者鼠标时的系统配置, 很多监控工具如jconsole需要将该值设置为true
configureHeadlessProperty();
// 2.1 获取运行监听管理器
SpringApplicationRunListeners listeners = getRunListeners(args);
// 发布ApplicationStartingEvent事件
listeners.starting();
try {
// 初始化默认应用参数类(不展开)
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 2.2 环境构建 (SpringCloud的父子容器创建入口). (发布ApplicationEnvironmentPreparedEvent事件)
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
// 设置要忽略的bean的参数spring.beaninfo.ignore(不展开)
configureIgnoreBeanInfo(environment);
// 打印出banner.txt并返回PrintedBanner打印类(不展开)
Banner printedBanner = printBanner(environment);
// 2.3 创建应用上下文(或者叫容器/IOC容器)
context = createApplicationContext();
// 获取异常报告器(不展开)
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
// 2.4 初始化应用上下文 (发布ApplicationContextInitializedEvent和ApplicationPreparedEvent事件)
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// 2.5 刷新应用上下文 (含添加JVM关闭时回调的钩子, 以便优雅的关闭运行的应用)
refreshContext(context);
// 2.6 应用上下文后处理(空方法)
afterRefresh(context, applicationArguments);
// 停止计时
stopWatch.stop();
if (this.logStartupInfo) {
// 输出日志记录执行主类名、启动耗时(不展开)
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
// 使用应用上下文发布ApplicationStartedEvent事件
listeners.started(context);
// 执行ApplicationRunner和CommandLineRunner
callRunners(context, applicationArguments);
} catch (Throwable ex) {
// 处理启动异常 (发布ApplicationFailedEvent事件)
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
// 使用应用上下文发布ApplicationReadyEvent事件
listeners.running(context);
} catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
2.1 获取运行监听管理器
SpringApplicationRunListeners 的作用是发布特定的事件, 这里我们管它为运行监听管理器
一般情况下, SpringApplicationRunListeners 中仅有一个EventPublishingRunListener元素. 下面看源码了解其创建过程
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
// 其中getSpringFactoriesInstances方法仅获取到默认的运行监听器EventPublishingRunListener
return new SpringApplicationRunListeners(logger,
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}
SpringApplicationRunListener的默认实现类如下图
SpringApplicationRunListeners最终结构如下:
SpringApplicationRunListeners主要代码如下.
class SpringApplicationRunListeners {
private final Log log;
// 运行监听器列表(一般仅有EventPublishingRunListener一个元素)
private final List<SpringApplicationRunListener> listeners;
SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners) {
this.log = log;
this.listeners = new ArrayList<>(listeners);
}
void starting() {
// 遍历运行监听器执行其starting方法
for (SpringApplicationRunListener listener : this.listeners) {
listener.starting();
}
}
void environmentPrepared(ConfigurableEnvironment environment) {...}
void contextPrepared(ConfigurableApplicationContext context) {...}
void contextLoaded(ConfigurableApplicationContext context) {...}
void started(ConfigurableApplicationContext context) {...}
void running(ConfigurableApplicationContext context) {...}
void failed(ConfigurableApplicationContext context, Throwable exception) {...}
//...
}
SpringApplicationRunListeners#starting遍历的SpringApplicationRunListener仅有EventPublishingRunListener, EventPublishingRunListener的主要代码如下. 不同方法发布着不同的SpringEvent事件
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
private final SpringApplication application;
private final String[] args;
private final SimpleApplicationEventMulticaster initialMulticaster;
public EventPublishingRunListener(SpringApplication application, String[] args) {
this.application = application;
this.args = args;
// 创建一个广播器. 实际发布事件的对象
this.initialMulticaster = new SimpleApplicationEventMulticaster();
for (ApplicationListener<?> listener : application.getListeners()) {
// 将SpringApplication创建时获取的ApplicationListener添加到广播器中
this.initialMulticaster.addApplicationListener(listener);
}
}
public void starting() {
// 使用广播器发布ApplicationStartingEvent事件
this.initialMulticaster.multicastEvent(
new ApplicationStartingEvent(this.application, this.args));
}
public void environmentPrepared(ConfigurableEnvironment environment) {
this.initialMulticaster.multicastEvent(
new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));
}
public void contextPrepared(ConfigurableApplicationContext context) {
this.initialMulticaster.multicastEvent(
new ApplicationContextInitializedEvent(this.application, this.args, context));
}
public void contextLoaded(ConfigurableApplicationContext context) {
//...
this.initialMulticaster.multicastEvent(
new ApplicationPreparedEvent(this.application, this.args, context));
}
public void started(ConfigurableApplicationContext context) {
context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context));
AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
}
public void running(ConfigurableApplicationContext context) {
context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context));
AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC);
}
public void failed(ConfigurableApplicationContext context, Throwable exception) {
ApplicationFailedEvent event = new ApplicationFailedEvent(this.application, this.args, context, exception);
//...
}
//...
}
由源码可知, 但执行SpringApplicationRunListeners.starting()方法时, 实际是调用EventPublishingRunListener的广播器发布ApplicationStartingEvent事件.
multicastEvent方法会筛选出SpringApplication添加的ApplicationListener监听器中 监听该事件的监听器, 执行onApplicationEvent方法接收事件处理. 默认都是同步方式执行时间发布和监听器处理的(广播器内的线程池默认为空)
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
// 获取监听该事件的监听器遍历
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
} else {
// 默认走同步调用
invokeListener(listener, event);
}
}
}
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
doInvokeListener(listener, event);
} catch (Throwable err) {
errorHandler.handleError(err);
}
} else {
doInvokeListener(listener, event);
}
}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
// 执行监听器的onApplicationEvent方法
listener.onApplicationEvent(event);
}
}
2.2 环境构建
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments) {
// 根据web应用类型创建Environment对象. 这里是servlet类型故创建出StandardServletEnvironment
ConfigurableEnvironment environment = getOrCreateEnvironment();
// 配置环境. 配置propertySource和activeProfiles
configureEnvironment(environment, applicationArguments.getSourceArgs());
// environment添加一个名字为configurationProperties的PropertySource
ConfigurationPropertySources.attach(environment);
// 环境准备完成, 发布ApplicationEnvironmentPreparedEvent事件.
// (SpringCloud会执行BootstrapApplicationListener. SpringCloud父子容器代码入口)
listeners.environmentPrepared(environment);
// 环境与当前应用程序绑定 (实际上SpringApplication和environment并没有绑定, 源码较深暂不深究)
bindToSpringApplication(environment);
// 转换为当前web应用类型的environment (SpringCloud父容器环境准备时会执行内部代码块, 子容器直接跳过)
if (!this.isCustomEnvironment) {
environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
deduceEnvironmentClass());
}
// environment可能发生变化, 重新再来一遍(确保configurationProperties属性源在第一个位置? 之前的attach有什么作用?)
ConfigurationPropertySources.attach(environment);
return environment;
}
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
// 设置属性类型转换器
if (this.addConversionService) {
ConversionService conversionService = ApplicationConversionService.getSharedInstance();
environment.setConversionService((ConfigurableConversionService) conversionService);
}
// 配置属性源 (默认没有执行任何操作)
configurePropertySources(environment, args);
// 配置profiles
configureProfiles(environment, args);
}
SpringApplication#configureEnvironment和ConfigurationPropertySources#attach方法都是给Environment添加PropertySource. 添加PropertySource的具体过程可查看 3.1 Environment添加PropertySource过程
listeners.environmentPrepared(environment);中会发布出ApplicationEnvironmentPreparedEvent事件. 若是SpringCloud项目, 则该事件会被BootstrapApplicationListener监听处理, 开始父容器的创建, 具体过程可查看 系列文章-SpringCloud父子容器源码浅析
2.3 创建应用上下文
应用上下文也经常被叫做容器, 这里的应用上下文也叫做Spring的IOC容器. 常见的应用上下文见 3.3 应用上下文
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch (this.webApplicationType) {
case SERVLET:
// servlet类型的web应用使用AnnotationConfigServletWebServerApplicationContext上下文
contextClass = Class.forName("org.springframework.boot."
+ "web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
break;
case REACTIVE:
contextClass = Class.forName("org.springframework."
+ "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";);
break;
default:
// 普通Spring项目使用AnnotationConfigApplicationContext上下文
contextClass = Class.forName("org.springframework.context."
+ "annotation.AnnotationConfigApplicationContext");
}
} catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
}
}
// 反射创建出应用上下文对象
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
这里为SERVLET类型的web应用类型, 故创建出的上下文为AnnotationConfigServletWebServerApplicationContext
以下为AnnotationConfigServletWebServerApplicationContext的继承类及字段
重要的字段如下:
- environment: 容器环境. 这里的实现类为StandardServletEnvironment
- beanFactoryPostProcessors: beanFactory的后置处理器列表
- parent: 父容器对象(SpringCloud时会有该值)
- beanFactory: bean工厂, 管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系. 这里的实现类为DefaultListableBeanFactory. 其继承的类及字段如下图
- beanPostProcessors: bean的后置处理器列表
- singletonObjects: 单例对象的缓存. bean名称 -> bean实例
- registeredSingletons: 已注册的单例的bean名称列表.按注册顺序排序(LinkedHashSet类型保证有序且不重复)
- beanDefinitionMap: bean定义的map. bean名称 -> bean定义
- beanDefinitionNames: bean定义名称列表, 按注册顺序排列
2.4 初始化应用上下文
后续的流程只关注SpringBoot的主线逻辑, 去掉SpringCloud的依赖, 不再提及SpringCloud
后续的流程只关注SpringBoot的主线逻辑, 去掉SpringCloud的依赖, 不再提及SpringCloud
后续的流程只关注SpringBoot的主线逻辑, 去掉SpringCloud的依赖, 不再提及SpringCloud
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments,
Banner printedBanner) {
// 为应用上下文绑定环境
context.setEnvironment(environment);
// 应用上下文的后置处理(不展开). 仅为上下文的beanFactory添加了ConversionService
postProcessApplicationContext(context);
// 执行SpringApplication的初始化器的initialize方法.
// SpringCloud的AncestorInitializer在这里执行完成父子容器绑定 (最后一次提及SpringCloud, 后续不再关注SpringCloud)
applyInitializers(context);
// 发布ApplicationContextInitializedEvent事件
listeners.contextPrepared(context);
// 打印启动使用的Profile参数
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// 获取上下文的bean工厂, 实现类为DefaultListableBeanFactory.
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// beanFactory缓存单例bean springApplicationArguments和springBootBanner
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
// beanFactory设置allowBeanDefinitionOverriding的值. 这里设置为false
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// 上下文添加惰性初始化beanFactory后置处理器. 这里不添加
if (this.lazyInitialization) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
// 获取所有的加载源. 例如SpringApplication.run(StudyApplication.class, args), StudyApplication就是加载源
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
// 重点: 加载 加载源, 为每个加载源构建bean定义对象, 缓存到beanFactory中(存储到beanDefinitionMap和beanDefinitionNames)
// 此方法较简单, 不展开, 可自行看源码
load(context, sources.toArray(new Object[0]));
// 为上下文添加SpringApplication的所有监听器, 并使用SpringApplication广播器发布ApplicationPreparedEvent事件
// 注: 后续发布的ApplicationStartedEvent和ApplicationReadyEvent事件都是通过上下文来发布的
listeners.contextLoaded(context);
}
protected void applyInitializers(ConfigurableApplicationContext context) {
for (ApplicationContextInitializer initializer : getInitializers()) {
Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),
ApplicationContextInitializer.class);
Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
// 执行初始化器的初始化方法
initializer.initialize(context);
}
}
主要内容:
- 执行SpringApplication的初始化器的initialize方法 (SpringCloud的AncestorInitializer在这里执行完成父子容器绑定)
- 发布ApplicationContextInitializedEvent事件
- beanFactory添加单例bean和设置属性
- 加载 加载源, 为每个加载源构建bean定义对象, 缓存到beanFactory中 (SpringBoot自动配置的入口)
- 发布ApplicationPreparedEvent事件
2.5 刷新应用上下文
private void refreshContext(ConfigurableApplicationContext context) {
// 添加JVM关闭时回调的钩子, 以便优雅的关闭运行的应用. 这里默认是会执行的
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
}
catch (AccessControlException ex) {
// Not allowed in some environments.
}
}
// 执行刷新
refresh((ApplicationContext) context);
}
public void registerShutdownHook() {
if (this.shutdownHook == null) {
// 创建一个线程作为钩子
this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
@Override
public void run() {
synchronized (startupShutdownMonitor) {
// 执行上下文的doClose()方法, 完成容器的关闭
doClose();
}
}
};
// 将创建的线程作为JVM关闭时调用的钩子. 待JVM正常关闭(如执行System.exit(0))会调用钩子
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
}
}
protected void refresh(ConfigurableApplicationContext applicationContext) {
// 使用应用上下文执行刷新方法. 最终执行到父类AbstractApplicationContext#refresh方法
applicationContext.refresh();
}
添加JVM关闭钩子, 以便JVM正常关闭时优雅的关闭容器. 例如执行System.exit(0)可正常的关闭JVM
执行AbstractApplicationContext#refresh. 这里是最核心的部分, 也是耗时最长的位置
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 2.5.1 刷新前预处理
// a.清空扫描器缓存 b.设置上下文active为激活状态 c.暂存监听器到earlyApplicationListeners
prepareRefresh();
// 2.5.2 获取beanFactory
// a.设置上下文的refreshed标记为true b.为beanFactory设置序列化id c.返回beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 2.5.3 beanFactory预处理
// a.对beanFactory的各种功能进行填充 b.添加bean的后置处理器、要忽略的*Aware接口、可注入的bean c.添加环境相关的bean到容器
prepareBeanFactory(beanFactory);
try {
// 2.5.4 beanFactory再次处理
// a.添加bean的后置处理器和其下忽略的接口ServletContextAware c.添加作用域和web相关的四个可注入的bean
postProcessBeanFactory(beanFactory);
// 2.5.5 调用BeanFactoryPostProcessor和其子类的后置处理方法(含解析@Configuration、@Bean等注解)
invokeBeanFactoryPostProcessors(beanFactory);
// 2.5.6 注册bean后置处理器BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// 2.5.7 初始化国际化处理器MessageSource
initMessageSource();
// 2.5.8 初始化事件广播器
initApplicationEventMulticaster();
// 2.5.9 为上下文设置themeSource和webServer
onRefresh();
// 2.5.10 为上下文的事件广播器添加监听器
registerListeners();
// 2.5.11 完成beanFactory的初始化(含实例化非惰性单例bean)
// a.设置beanFactory临时的类加载器等 b.冻结所有bean定义 c.实例化所有剩余的非惰性单例bean
finishBeanFactoryInitialization(beanFactory);
// 2.5.12 上下文完成刷新
// a.清除上下文资源缓存 b.为上下文添加生命周期处理器并执行刷新过程 c.发布ContextRefreshedEvent事件
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + ex);
}
// 销毁所有的单例bean及其他缓存
destroyBeans();
// beanFactory的序列化id置为空, 设置active标志为false
cancelRefresh(ex);
throw ex;
} finally {
// 重置Spring的公共反射元数据缓存
resetCommonCaches();
}
}
}
具体内容:
2.5.1 刷新前预处理
a.清空扫描器缓存 b.设置上下文active为激活状态 c.暂存监听器到earlyApplicationListeners
2.5.2 获取beanFactory
a.设置上下文的refreshed标记为true b.为beanFactory设置序列化id c.返回beanFactory
2.5.3 beanFactory预处理
a.对beanFactory的各种功能进行填充 b.添加bean的后置处理器和要忽略的*Aware接口 c.添加环境相关的bean到容器
2.5.4 beanFactory再次处理
a.添加bean的后置处理器 b.添加要忽略的接口ServletContextAware c.添加添加作用域和ResolvableDependency
2.5.5 调用BeanFactoryPostProcessor和其子类的后置处理方法
(含解析@Configuration、@ComponentScan、@ComponentScans、@Import、@Bean注解)
2.5.6 注册bean后置处理器BeanPostProcessor
2.5.7 初始化国际化处理器MessageSource
2.5.8 初始化事件广播器
2.5.9 为上下文设置themeSource和webServer
2.5.10 为上下文的事件广播器添加监听器
2.5.11 完成beanFactory的初始化(含实例化非惰性单例bean)
a.设置beanFactory临时的类加载器等 b.冻结所有bean定义 c.实例化所有剩余的非惰性单例bean
2.5.12 上下文完成刷新
a.清除上下文资源缓存 b.为上下文添加生命周期处理器并执行刷新过程 c.发布ContextRefreshedEvent
下面看下里面具体方法做了什么
2.5.1 刷新前预处理
执行AnnotationConfigServletWebServerApplicationContext#prepareRefresh
protected void prepareRefresh() {
// 扫描器 清除本地元数据缓存(如果有的话),删除所有缓存的类元数据
this.scanner.clearCache();
// 执行父类AbstractApplicationContext#prepareRefresh
super.prepareRefresh();
}
// 执行父类AbstractApplicationContext#prepareRefresh
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
// 设置active为激活状态
this.active.set(true);
if (logger.isDebugEnabled()) {//...}
// 初始化上下文环境中所有的占位符属性源(debug发现其实不满足条件什么都没做)
initPropertySources();
// 验证指定的属性是否存在, 若存在且解析为空值则抛出异常.
// (debug发现requiredProperties为空不满足条件什么都没做)
getEnvironment().validateRequiredProperties();
if (this.earlyApplicationListeners == null) {
// 刷新前暂存应用监听器(为什么这么做?). 启动时默认执行这里
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
} else {
// 使用earlyApplicationListeners 重置当前的监听器列表.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
this.earlyApplicationEvents = new LinkedHashSet<>();
}
a.清空扫描器缓存
b.设置上下文active为激活状态
c.暂存监听器到earlyApplicationListeners
2.5.2 获取beanFactory
执行AbstractApplicationContext#obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 执行父类GenericApplicationContext#refreshBeanFactory
refreshBeanFactory();
// 直接返回beanFactory
return getBeanFactory();
}
// 执行父类GenericApplicationContext#refreshBeanFactory
protected final void refreshBeanFactory() throws IllegalStateException {
// 设置上下文的refreshed标记为true
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
// 设置beanFactory的序列化id为"application"
this.beanFactory.setSerializationId(getId());
}
a.设置上下文的refreshed标记为true
b.为beanFactory设置序列化id
c.返回beanFactory
2.5.3 beanFactory预处理
执行AbstractApplicationContext#prepareBeanFactory
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置类加载器、Bean表达式解析器、属性编辑注册器 (本文都是瞎取名, 不要在意细节)
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 注册一个ApplicationContextAwareProcessor的bean后置处理器, 注册要忽略的六个Aware接口
// (该bean后置处理器就是用于注入这些Aware接口的属性bean的, XxxAware作用就是将xxx的bean注入实现类中)
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// 注册四个可注入的bean(XxxAware的可注入的bean就是xxx)
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 添加一个ApplicationListenerDetector的bean后置处理器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 存在loadTimeWeaver的bean时, 添加bean后置处理器LoadTimeWeaverAwareProcessor和临时的类加载器(默认不执行)
if (beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 添加环境相关的几个bean到容器中
if (!beanFactory.containsLocalBean("environment")) {
beanFactory.registerSingleton("environment", getEnvironment());
}
if (!beanFactory.containsLocalBean("systemProperties")) {
beanFactory.registerSingleton("systemProperties", getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean("systemEnvironment")) {
beanFactory.registerSingleton("systemEnvironment", getEnvironment().getSystemEnvironment());
}
}
a.对beanFactory的各种功能进行填充(解析器, 属性编辑注册器等)
b.注册bean的后置处理器ApplicationContextAwareProcessor及注册忽略其解析的六个Aware接口, 注册四个可注入的bean
c.添加环境相关的几个bean到容器
补充1:
- beanFactory的containsLocalBean方法: 查找当前bean工厂是否包含该bean或其bean的定义
- beanFactory的containsBean方法: 查找当前bean工厂是否包含该bean或其bean的定义, 当前bean工厂没有则再递归其父bean工厂去查找;
补充2: 注意BeanFactoryPostProcessor与BeanPostProcessor是不同的.
更多请查看: 3.4 BeanFactoryPostProcessor与BeanPostProcessor的区别
2.5.4 beanFactory再次处理
执行AnnotationConfigServletWebServerApplicationContext#postProcessBeanFactory方法
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 执行父类ServletWebServerApplicationContext.postProcessBeanFactory
super.postProcessBeanFactory(beanFactory);
// basePackages不为空则扫描包(默认不执行)
if (this.basePackages != null && this.basePackages.length > 0) {
this.scanner.scan(this.basePackages);
}
// annotatedClasses不为空则注册添加(默认不执行)
if (!this.annotatedClasses.isEmpty()) {
this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
}
// 执行父类ServletWebServerApplicationContext.postProcessBeanFactory
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 添加bean的后置处理器WebApplicationContextServletContextAwareProcessor
beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
// 添加依赖注入时要忽略的接口ServletContextAware
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
// 为beanFactory添加作用域和web相关的四个可注入的bean
registerWebApplicationScopes();
}
a.添加bean的后置处理器WebApplicationContextServletContextAwareProcessor和其下要忽略的ServletContextAware接口
b.添加添加作用域和web相关的四个可注入的bean(ServletRequest, ServletResponse, HttpSession, WebRequest)
2.5.5 调用BeanFactoryPostProcessor和其子类的后置处理方法(含解析@Configuration、@Bean等注解)
执行父类AbstractApplicationContext.invokeBeanFactoryPostProcessors
// 执行父类AbstractApplicationContext.invokeBeanFactoryPostProcessors
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 执行PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 存在loadTimeWeaver的bean时, 添加bean后置处理器LoadTimeWeaverAwareProcessor和临时的类加载器(默认不执行)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
// 执行PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
// 1. 先执行上下文中所有BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
// 注: BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
// 2. 执行beanFactory下所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 重要: 在这里执行了最重要的一个后置处理器ConfigurationClassPostProcessor. 解析加了@Configuration的配置类,
// 还会解析@ComponentScan、@ComponentScans注解扫描的包, 以及解析@Import等注解
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 3. 执行beanFactory下所有实现Ordered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 3. 执行beanFactory下其他的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,
// 直到没有其他BeanDefinitionRegistryPostProcessors出现为止
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// 4. 执行上下文和beanFactory中所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 5. 执行上下文中所有普通的BeanFactoryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// 直接调用postProcessBeanFactory方法(默认不执行此代码块)
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 分类获取beanFactory中实现了PriorityOrdered, 实现了Ordered, 和其余的BeanFactoryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// 已执行的bean则跳过, 这里跳过属于BeanDefinitionRegistryPostProcessor的BeanFactoryPostProcessor
} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 6. 执行beanFactory下实现了PriorityOrdered的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 7. 执行beanFactory下实现了Ordered的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 8. 执行beanFactory下其他的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
beanFactory.clearMetadataCache();
}
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
// 执行postProcessBeanDefinitionRegistry
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
// 执行postProcessBeanFactory
postProcessor.postProcessBeanFactory(beanFactory);
}
}
BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口
BeanFactoryPostProcessor含有方法postProcessBeanFactory (后置处理bean工厂)
BeanDefinitionRegistryPostProcessor含有方法postProcessBeanDefinitionRegistry (后置处理bean定义注册)
这里调用了一个很重要的bean工厂的后置处理器ConfigurationClassPostProcessor. 它会解析加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解. 想进一步了解的可以查看文章 ConfigurationClassPostProcessor —— Spring中最!最!最!重要的后置处理器!没有之一!!!
a.执行上下文中BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
b.执行beanFactory中BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry (按实现注解PriorityOrdered,实现注解Ordered,其他 的顺序执行)
c.执行上下文和beanFactory中BeanDefinitionRegistryPostProcessor#postProcessBeanFactory
d.执行上下文中普通的BeanFactoryPostProcessor#postProcessBeanFactory
e.执行beanFactory中普通BeanFactoryPostProcessor#postProcessBeanFactory (按实现注解PriorityOrdered,实现注解Ordered,其他 的顺序执行)
注:
- 一般情况下, bean定义由ConfigurationClassPostProcessor和MapperScannerConfigurer两个BeanDefinitionRegistryPostProcessor完成注册的, 大部分的bean定义都是由ConfigurationClassPostProcessor注册的
- 注册后的bean定义, 在AbstractApplicationContext#finishBeanFactoryInitialization中创建出单例bean
2.5.6 注册bean后置处理器BeanPostProcessor
注意BeanFactoryPostProcessor与BeanPostProcessor是不同的.
更多请查看: 3.4 BeanFactoryPostProcessor与BeanPostProcessor的区别
执行AbstractApplicationContext#registerBeanPostProcessors
// 执行AbstractApplicationContext#registerBeanPostProcessors
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
// 执行PostProcessorRegistrationDelegate#registerBeanPostProcessors
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 获取BeanPostProcessor类型的的所有后置处理器名称
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// a. 添加一个bean后置处理器BeanPostProcessorChecker(作用: 当一个bean没有被任一BeanPostProcessor处理时输出日志)
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// b. 分类获取beanFactory中实现了PriorityOrdered, 实现了Ordered, 和其余的BeanPostProcessor. 注册到beanFactory中
// 另外按顺序记录下属于MergedBeanDefinitionPostProcessor的BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// b1. 注册所有实现PriorityOrdered的BeanPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// b2. 注册所有实现Ordered的BeanPostProcessor
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// b3. 注册其他的BeanPostProcessor
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// c.重新注册属于MergedBeanDefinitionPostProcessor的BeanPostProcessor (重新注册为了排序到最后面)
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// d.重新注册ApplicationListenerDetector这个后置处理器 (重新注册为了排序到最后面)
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
// 将beanPostProcessor注册到beanFactory中
beanFactory.addBeanPostProcessor(postProcessor);
}
}
a.添加一个bean后置处理器BeanPostProcessorChecker
b.分类获取beanFactory中实现了PriorityOrdered, 实现了Ordered, 和其余的BeanPostProcessor. 注册到beanFactory中
c.重新注册属于MergedBeanDefinitionPostProcessor的BeanPostProcessor
d.重新注册ApplicationListenerDetector这个后置处理器
2.5.7 初始化国际化处理器MessageSource
执行AbstractApplicationContext#initMessageSource
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 判断beanFactory是否已存在messageSource的bean(默认是不存在的)
if (beanFactory.containsLocalBean("messageSource")) {
// 设置messageSource到上下文中
this.messageSource = beanFactory.getBean("messageSource", MessageSource.class);
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// 绑定父子上下文中messageSource的父子关系
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
} else {
// 创建一个新的MessageSource
DelegatingMessageSource dms = new DelegatingMessageSource();
// 绑定父子上下文中messageSource的父子关系
dms.setParentMessageSource(getInternalParentMessageSource());
// 设置到上下文中
this.messageSource = dms;
// 注册bean到beanFactory中
beanFactory.registerSingleton("messageSource", this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
2.5.8 初始化事件广播器
执行AbstractApplicationContext#initApplicationEventMulticaster
注意: 这里是设置上下文和beanFactory的事件广播器, 与SpringApplication的事件广播器是没有关系的
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 判断beanFactory是否已存在applicationEventMulticaster的bean(默认是不存在的)
if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
// 设置applicationEventMulticaster到上下文中
this.applicationEventMulticaster =
beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
} else {
// 创建新的时间广播器, 设置到上下文中
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
// 注册bean到beanFactory中
beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
2.5.9 为上下文设置themeSource和webServer
// 执行ServletWebServerApplicationContext#onRefresh
protected void onRefresh() {
// 执行GenericWebApplicationContext#onRefresh
super.onRefresh();
try {
// 创建webServer
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
// 执行org.springframework.web.context.support.GenericWebApplicationContext#onRefresh
protected void onRefresh() {
// 为上下文设置主题源 ThemeSource
this.themeSource = UiApplicationContextUtils.initThemeSource(this);
}
private void createWebServer() {
// 获取应用上下文中的webServer(默认不存在)
WebServer webServer = this.webServer;
// 获取应用上下文中的Servlet上下文(默认不存在)
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
ServletWebServerFactory factory = getWebServerFactory();
// 创建出webServer实例并设置到上下文中
this.webServer = factory.getWebServer(getSelfInitializer());
// 为beanFactory注册webServer优雅关闭的bean
getBeanFactory().registerSingleton("webServerGracefulShutdown",
new WebServerGracefulShutdownLifecycle(this.webServer));
// 为beanFactory注册webServer启停的bean
getBeanFactory().registerSingleton("webServerStartStop",
new WebServerStartStopLifecycle(this, this.webServer));
} else if (servletContext != null) {
try {
getSelfInitializer().onStartup(servletContext);
} catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context", ex);
}
}
// 初始化上下文Environment中名为servletContextInitParams的属性源
initPropertySources();
}
2.5.10 为上下文的事件广播器添加监听器
执行AbstractApplicationContext#registerListeners
protected void registerListeners() {
// 为上下文的事件广播器添加 上下文中的应用监听器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 为上下文的事件广播器添加 beanFactory中的监听器bean的名字(先不添加bean, 待后置处理bean后再添加)
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 发布早期的应用程序事件 (默认earlyApplicationEvents为空, 不执行发布)
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
2.5.11 完成beanFactory的初始化(含实例化非惰性单例bean)
执行AbstractApplicationContext#finishBeanFactoryInitialization
重点: 在这里实例化剩余的所有的非惰性的单例bean
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 如果beanFactory中包含conversionService的bean且类型符合, 则重置beanFactory的conversionService (默认不包含)
if (beanFactory.containsBean("conversionService") &&
beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService(beanFactory.getBean("conversionService", ConversionService.class));
}
// 如果没有内嵌属性值解析器, 则添加 (默认不执行)
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 如果有LoadTimeWeaverAware的bean名字, 则创建出这些bean (默认没有)
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 置空临时的类加载器
beanFactory.setTempClassLoader(null);
// 冻结所有bean定义, 已注册的bean定义不会被修改或进一步后处理
beanFactory.freezeConfiguration();
// 实例化所有剩余的非惰性单例bean(非延迟加载的bean)
beanFactory.preInstantiateSingletons();
}
beanFactory.preInstantiateSingletons()中实例化所有剩余的非惰性单例bean. 待有空时再浅析下这块的源码
2.5.12 完成上下文刷新
进入AbstractApplicationContext#finishRefresh
protected void finishRefresh() {
// 清除上下文资源缓存(例如扫描ASM元数据)
clearResourceCaches();
// 为上下文添加生命周期处理器
initLifecycleProcessor();
// 生命周期处理器刷新过程(例如webServerStartStop执行启动start处理)
getLifecycleProcessor().onRefresh();
// 发布上下文已刷新事件ContextRefreshedEvent
publishEvent(new ContextRefreshedEvent(this));
// 视图器注册上下文(作用未了解)
LiveBeansView.registerApplicationContext(this);
}
// 执行AbstractApplicationContext#initLifecycleProcessor
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 判断beanFactory中是否有lifecycleProcessor的bean或其定义 (默认是有的)
if (beanFactory.containsLocalBean("lifecycleProcessor")) {
// 设置lifecycleProcessor到上下文中
this.lifecycleProcessor = beanFactory.getBean("lifecycleProcessor", LifecycleProcessor.class);
if (logger.isTraceEnabled()) {
logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
} else {
// 没有则创建一个lifecycleProcessor, 设置到上下文中并注册到beanFactory中
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isTraceEnabled()) {
logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
}
}
}
2.6 应用上下文后处理
protected void afterRefresh(ConfigurableApplicationContext context, ApplicationArguments args) {
}
空实现方法
作用?
可以创建一个自己的SpringApplication继承SpringApplication, 重写afterRefresh方法用来执行自己自定义的逻辑
2.7 执行Runner, 启动就绪
执行Runner前, 使用应用上下文发布ApplicationStartedEvent事件 listeners.started(context);
private void callRunners(ApplicationContext context, ApplicationArguments args) {
List<Object> runners = new ArrayList<>();
// 获取类型为ApplicationRunner和CommandLineRunner所有的Runner
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
AnnotationAwareOrderComparator.sort(runners);
// 遍历执行Runner的run方法
for (Object runner : new LinkedHashSet<>(runners)) {
if (runner instanceof ApplicationRunner) {
callRunner((ApplicationRunner) runner, args);
}
if (runner instanceof CommandLineRunner) {
callRunner((CommandLineRunner) runner, args);
}
}
}
private void callRunner(ApplicationRunner runner, ApplicationArguments args) {
try {
(runner).run(args);
}
catch (Exception ex) {
throw new IllegalStateException("Failed to execute ApplicationRunner", ex);
}
}
说明:
- 默认情况下, SpringBoot项目是没有添加ApplicationRunner和CommandLineRunner的bean的, 故runners列表为空, 不会执行任何操作
- Runner目前只是提供给我们做扩展, 我们可以自定义一个Runner, 添加@Component注解, 待Spring启动完成时执行我们的Runner完成我们的自定义逻辑
执行Runner后, 使用应用上下文发布ApplicationReadyEvent事件 listeners.running(context);
三. 拓展
3.1 Environment添加PropertySource过程
继承体系和实现如下:
内部属性如下:
这里分析SpringBoot启动中StandardServletEnvironment添加propertySources的过程.
3.1.1 执行父类AbstractEnvironment的构造器方法
private final MutablePropertySources propertySources = new MutablePropertySources();
public AbstractEnvironment() {
customizePropertySources(this.propertySources);
}
此时: propertySources.propertySourceList为空列表
3.1.2 执行StandardServletEnvironment的customizePropertySources方法
添加了servletConfigInitParams和servletContextInitParams两个propertySource. 空对象里面没有属性值
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(new StubPropertySource("servletConfigInitParams"));
propertySources.addLast(new StubPropertySource("servletContextInitParams"));
if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
propertySources.addLast(new JndiPropertySource("jndiProperties"));
}
super.customizePropertySources(propertySources);
}
3.1.3 执行父类StandardEnvironment的customizePropertySources方法
添加了systemProperties和systemEnvironment两个propertySource.
protected void customizePropertySources(MutablePropertySources propertySources) {
// 获取项目运行属性. 如: java.vm.info -> mixed mode
propertySources.addLast(new PropertiesPropertySource("systemProperties", getSystemProperties()));
// 获取计算机环境变量. 如: JAVA_HOME -> F:\jdk
propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment", getSystemEnvironment()));
}
3.1.4 执行ConfigurationPropertySources#attach方法
添加了configurationProperties这个propertySource.
public static void attach(Environment environment) {
Assert.isInstanceOf(ConfigurableEnvironment.class, environment);
MutablePropertySources sources = ((ConfigurableEnvironment) environment).getPropertySources();
PropertySource<?> attached = sources.get("configurationProperties");
if (attached != null && attached.getSource() != sources) {
sources.remove("configurationProperties");
attached = null;
}
if (attached == null) {
sources.addFirst(new ConfigurationPropertySourcesPropertySource("configurationProperties",
new SpringConfigurationPropertySources(sources)));
}
}
3.1.5 SpringCloud中存在父子容器创建过程, 父容器创建完成后, 会给子容器Environment添加一个propertySource
3.1.6 ConfigFileApplicationListener执行EnvironmentPostProcessor加载其余的配置文件
环境准备好后, 监听ApplicationEnvironmentPreparedEvent事件, 其中ConfigFileApplicationListener也会监听该事件进行处理
ConfigFileApplicationListener执行流程如下(感兴趣的可以去看源码, 源码不复杂):
- 遍历EnvironmentPostProcessor(ConfigFileApplicationListener也是环境后置处理器, 也加到列表遍历执行). 处理器实现类在spring.factories中
- 执行postProcessEnvironment方法 (以下为ConfigFileApplicationListener的后置处理逻辑, 其他处理器请看源码)
- 添加一个名为random的propertySource到Environment
- 添加一个null的profile, 添加spring.profiles.active和spring.profiles.include下的值, 遍历profile列表
- 获取文件文件夹地址和文件名(不含后缀)
- ConfigFileApplicationListener.Loader#getSearchLocations()获取指定的配置文件路径, 没有指定则返回默认路径classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/
- ConfigFileApplicationListener.Loader#getSearchNames获取文件名, 如bootstrap, application
- 遍历加载器PropertySourceLoader, 拼接出文件完整路径, 判断文件资源是否存在, 存在则加载解析文件. PropertySourceLoader常见实现类如下
- YamlPropertySourceLoader 加载yaml和yml结尾的配置文件
- PropertiesPropertySourceLoader 加载properties和xml结尾的配置文件
- 使用ConfigFileApplicationListener.Loader#loaded属性暂存各个profile下的读取的配置文件属性信息
- 添加loaded属性的所有PropertySource到Environment中 (ConfigFileApplicationListener.Loader#addLoadedPropertySource中完成添加)
- 添加的 propertySource都是有顺序的, 有profile的必定在没有的前面, 例如application-dev.yml必定在application.yml前
3.2 SpringCloud的父子容器
见系列文章-SpringCloud父子容器源码浅析
3.3 应用上下文
Spring容器最基本的接口就是BeanFactory. BeanFactory负责配置、创建、管理Bean.ApplicationContext由BeanFactory派生而来
应用上下文也经常被叫做容器
常见的实现类有:
- ClassPathXmlApplicationContext:可以加载类路径下的配置文件(要求配置文件必须在类路径之下)
- FileSystemXmlApplicationContext:可以加载磁盘中任意路径下的配置文件(要求具有访问权限)
- AnnotationConfigApplicationContext:用于读取注解创建容器
- AnnotationConfigServletWebServerApplicationContext:SpringBoot的servlet项目使用的容器实现
主要的继承关系图如下:
3.4 BeanFactoryPostProcessor与BeanPostProcessor的区别
- BeanFactoryPostProcessor: bean工厂的后置处理器, 针对BeanFactory的扩展,修改bean的定义属性(bean定义之后, 实例化bean之前)
- BeanPostProcessor: bean的后置处理器, 针对Bean的扩展,对bean进行处理(实例化bean之后, 初始化bean前后调用)
区别对比如下如: 图片来源: Spring面试系列—BeanFactoryPostProcessor和BeanPostProcessor的区别
四. 思考
- ConfigurationPropertySources.attach(environment)为什么执行两次? 第一次是否多余? 添加的configurationProperties属性源的作用是什么?
- SpringCloud父子容器的作用? 为什么这样设计?
- SpringApplication#afterRefresh是空实现, 它的作用是什么? 为什么这样设计?
五. 参考文档
springboot启动过程源码分析: https://blog.csdn.net/wufaqidong1/article/details/126236638
springboot启动流程源码解析: https://blog.csdn.net/promsing/article/details/126469944