spring boot 之application
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 Collection getSpringFactoriesInstances(Class type,
Class>[] parameterTypes, Object... args) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// Use names and ensure unique to protect against duplicates
Set names = new LinkedHashSet<>(
//重点在这个方法
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List 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
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
