ApplicationContext 分别继承了以下接口:
ResourcePatternResolver:解析和加载资源
MessageSource:国际化
BeanFactory:Bean 容器
EnvironmentCapable:获取应用环境配置
ApplicationEventPublisher:发布事件
@SpringBootApplication
public class SpringSourceCodeTestApplication {
public static void main(String[] args) {
ConfigurableApplicationContext springBootContext = SpringApplication.run(SpringSourceCodeTestApplication.class, args);
}
}
run 方法向下追溯可以追溯到org.springframework.boot.SpringApplication#run(java.lang.Class<?>[], java.lang.String[])方法,该方法可以分为两个步骤,第一个步骤为创建SpringApplication对象,第二个步骤为基于该对象调用run方法
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return (new SpringApplication(primarySources)).run(args);
}
创建SpringApplication对象可以分为以下几步:
1. 使用常量值初始化一些字段
2. 设置主类
3. 推断web应用类型
4. 从代码目录和jar包目录下的META-INF/spring.factories文件中加载key为org.springframework.boot.BootstrapRegistryInitializer的values,并基于这些values对应的类创建对象保存到
bootstrapRegistryInitializers容器中
5. 从代码目录和jar包目录下的META-INF/spring.factories文件中加载key为org.springframework.context.ApplicationContextInitializer的values,并基于这些values对应的类创建对象保存到listeners容器中
6. 从代码目录和jar包目录下的META-INF/spring.factories文件中加载key为org.springframework.context.ApplicationListener的values,并基于这些values对应的类创建对象保存到initializers 容器中
7. 基于当前的栈查找main 方法所属的类,基于该类创建实例并赋值给mainApplicationClass
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = Collections.emptySet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
this.applicationStartup = ApplicationStartup.DEFAULT;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}
run方法可以分为以下几步:
1. 创建一个bootStrapContext容器,并基于initializers中的initializer回调初始化
2. 配置java.awt.headless属性
3. 构建事件发布器:从代码目录和jar包目录下的META-INF/spring.factories文件中加载key为org.springframework.boot.SpringApplicationRunListener的values,并基于这些values对应的类创建对象保存到
SpringApplicationRunListeners对象中
4. 使用事件发布器发布容器启动事件
5. 设置应用环境配置
6. 打印Banner
7. 创建context实例
8. 准备容器
9. 刷新容器
10. 容器后处理
11. 发布容器已启动事件
public ConfigurableApplicationContext run(String... args) {
long startTime = System.nanoTime();
DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
ConfigurableApplicationContext context = null;
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
Throwable ex;
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);
}
listeners.started(context, timeTakenToStartup);
this.callRunners(context, applicationArguments);
} catch (Throwable var12) {
ex = var12;
this.handleRunFailure(context, ex, listeners);
throw new IllegalStateException(ex);
}
try {
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
listeners.ready(context, timeTakenToReady);
return context;
} catch (Throwable var11) {
ex = var11;
this.handleRunFailure(context, ex, (SpringApplicationRunListeners)null);
throw new IllegalStateException(ex);
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。