SpringApplication 准备阶段
配置 Spring Boot Bean 源
通过 Java 配置 Class 或 XML 上下文配置文件集合,用于 Spring Boot BeanDefinitionLoader 读取 ,并且将配置源解析加载为
Spring Bean 定义
推断 Web 应用类型
根据当前应用 ClassPath 中是否存在相关实现类来推断 Web 应用的类型,包括:
Web Reactive: WebApplicationType.REACTIVE
Web Servlet: WebApplicationType.SERVLET
非 Web: WebApplicationType.NONE
//参考 org.springframework.boot.SpringApplication#deduceWebApplicationType
private WebApplicationType deduceWebApplicationType() {
if (ClassUtils.isPresent(REACTIVE_WEB_ENVIRONMENT_CLASS, null)
&& !ClassUtils.isPresent(MVC_WEB_ENVIRONMENT_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
for (String className : WEB_ENVIRONMENT_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
return WebApplicationType.SERVLET;
}
推断引导类(Main Class)
根据 Main 线程执行堆栈判断实际的引导类
//参考方法: org.springframework.boot.SpringApplication#deduceMainApplicationClass
private Class<?> deduceMainApplicationClass() {
try {
StackTraceElement[] stackTrace = (new RuntimeException()).getStackTrace();
StackTraceElement[] var2 = stackTrace;
int var3 = stackTrace.length;
for(int var4 = 0; var4 < var3; ++var4) {
StackTraceElement stackTraceElement = var2[var4];
if ("main".equals(stackTraceElement.getMethodName())) {
return Class.forName(stackTraceElement.getClassName());
}
}
} catch (ClassNotFoundException var6) {
}
return null;
}
加载应用上下文初始器 ( ApplicationContextInitializer )
利用 Spring 工厂加载机制,实例化 ApplicationContextInitializer 实现类,并排序对象集合。说白了就是从spring.factories配置文件中读取org.springframework.context.ApplicationContextInitializer属性。
//参考 org.springframework.boot.SpringApplication#deduceMainApplicationClass
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// Use names and ensure unique to protect against duplicates
Set<String> names = new LinkedHashSet<>(
//重点在这个方法
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names);
//并进行排序
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
核心实现就是利用 SpringFactoriesLoader 到META-INF/spring.factories中去加载资源,并将读取到的实例进行创建并排序。
加载应用事件监听器( ApplicationListener )
利用 Spring 工厂加载机制,实例化 ApplicationListener 实现类,并排序对象集合,因为其与上文初始化的加载一致,所以略过。
SpringApplication 运行阶段
加载 SpringApplication 运行监听器( SpringApplicationRunListeners )
利用 Spring 工厂加载机制,读取 SpringApplicationRunListener 对象集合,并且封装到组合类
SpringApplicationRunListeners
默认全局只有一个
# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener
运行 SpringApplication 运行监听器( SpringApplicationRunListeners )
public interface SpringApplicationRunListener {
//Spring 应用刚启动
void starting();
//ConfigurableEnvironment 准备妥当,允许将其调整
void environmentPrepared(ConfigurableEnvironment environment);
//ConfigurableApplicationContext 准备妥当,允许将其调整
void contextPrepared(ConfigurableApplicationContext context);
//ConfigurableApplicationContext 已装载,但仍未启动
void contextLoaded(ConfigurableApplicationContext context);
//ConfigurableApplicationContext 已启动,此时 Spring Bean 已初始化完成
void started(ConfigurableApplicationContext context);
//Spring 应用正在运行
void running(ConfigurableApplicationContext context);
//Spring 应用运行失败
void failed(ConfigurableApplicationContext context, Throwable exception);
}
创建 Spring 应用上下文( ConfigurableApplicationContext )
//根据准备阶段的推断 Web 应用类型创建对应的 ConfigurableApplicationContext 实例:
//Web Reactive:
AnnotationConfigReactiveWebServerApplicationContext
//Web Servlet:
AnnotationConfigServletWebServerApplicationContext
//非 Web:
AnnotationConfigApplicationContext
创建 Environment
根据准备阶段的推断 Web 应用类型创建对应的 ConfigurableEnvironment 实例:
Web Reactive: StandardEnvironment
Web Servlet: StandardServletEnvironment
非 Web: StandardEnvironment