SpringBoot 的启动流程
SpringBoot 的启动流程
一、 生成SpringApplication对象
1. webApplicationType = 推测web应用的类型(NODE(普通项目)、SERVLET(Servlet web项目)、 * REACTIVE(响应式项目 flux)
2. 从spring.factories 中获取BootstrapRegistryInitializer对象
3. initializers = 从spring.factories中获取ApplicationContextInitializer对象
4. isteners = 从spring.factories中获取ApplicationListener对象
二、 该方法启动SpringBoot项目
1. 调用run方法–> (new SpringApplication(primarySources)).run(args);
2. 先生成SpringApplication对象,之后调用run方法 primarySource --> 传进去的的类相当于配置类,可以为一个数组。
3. SpringApplicationListener.starting()
4. 创建一个Spring容器
5. ApplicationContextInitializer—>初始化Spring容器
6.SpringApplicationRunListener.contextPrepared()
7. 把传给run方法的的配置类注册成bean
8. SpringApplicationRunListener.contextLoaded()会
9. 解析配置类、扫描、启动Tomcat/Jetty/Undertow
(AutoConfigurationImportSelector、DeferredImportSelector)
10. SpringApplicationRunListener.started()
11. callRunners–>ApplicationRunner、CommandLineRunner
12. SpringApplicationListener.ready()
/**
* 生成SpringApplication对象
* webApplicationType = 推测web应用的类型(NODE(普通项目)、SERVLET(Servlet web项目)、 * REACTIVE(响应式项目 flux)
* 从spring.factories 中获取BootstrapRegistryInitializer对象
* initializers = 从spring.factories中获取ApplicationContextInitializer对象
* listeners = 从spring.factories中获取ApplicationListener对象
*
* 该方法启动SpringBoot项目
* 调用run方法--> (new SpringApplication(primarySources)).run(args);
* 先生成SpringApplication对象,之后调用run方法 primarySource --> 传进去的的类相当于配 置类,可以为一个数组。
* SpringApplicationListener.starting()
* 创建一个Spring容器
* ApplicationContextInitializer--->初始化Spring容器
* SpringApplicationRunListener.contextPrepared()
* 把传给run方法的的配置类注册成bean
* SpringApplicationRunListener.contextLoaded()
* 会解析配置类、扫描、启动 Tomcat/Jetty/Undertow(AutoConfigurationImportSelector、DeferredImportSelector)
* SpringApplicationRunListener.started()
* callRunners-->ApplicationRunner、CommandLineRunner
* SpringApplicationListener.ready()
*
*/
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;
//设置applicationContextFactory类型
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));
//判断SpringBoot项目类型 webApplicationType=NODE、Servlet、Reactive
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();
}
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);//执行监听器
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);//初始化默认应用参数类、命令行参数
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);//获得系统环境以及配置信息
this.configureIgnoreBeanInfo(environment);//排除某些bean
Banner printedBanner = this.printBanner(environment);//获得打印banner的信息
context = this.createApplicationContext();//创建ApplicationContext即Spring容器
context.setApplicationStartup(this.applicationStartup);
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);//SpringApplicationRunListener.contextPrepared()
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);//执行监听器
//callRunners-->ApplicationRunner、CommandLineRunner
this.callRunners(context, applicationArguments);
} catch (Throwable var12) {
//处理异常
this.handleRunFailure(context, var12, listeners);
throw new IllegalStateException(var12);
}
try {
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
//执行ready
listeners.ready(context, timeTakenToReady);
return context;
} catch (Throwable var11) {
this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var11);
}
}