spring boot 启动流程源码阅读解析
- 创建SpringApplication对象
- 调用SpringApplication run 实现启动同时返回当前的容器上下文
- 创建SpringApplication对象实现SpringBoot初始化操作
@SpringBootApplication
public class HzDemoApplication {
public static void main(String[] args) {
SpringApplication.run(HzDemoApplication.class, args);
}
}
- 在SpringApplication构造函数中获取当前应用的启动类型
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();
}
- setInitializers 读取SpringBoot包下面的META-INF/spring.factories 获取到对应ApplicationContextInitializer 的实现类装配到集合(initializers)中
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
- setListeners 读取SpringBoot包下面的META-INF/spring.factories 获取到对应ApplicationListener 的实现类装配到集合(listeners)中
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
- mainApplicationClass 获取当前运行的主函数
this.mainApplicationClass = this.deduceMainApplicationClass();
- 调用SpringApplication run方法实现启动
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);
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) {
this.handleRunFailure(context, var12, listeners);
throw new IllegalStateException(var12);
}
try {
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
listeners.ready(context, timeTakenToReady);
return context;
} catch (Throwable var11) {
this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var11);
}
}
- long startTime = System.nanoTime(); 记录启动时间
- getRunListeners(args);读取我们的ETA-INF/spring.factories SpringApplicationRunListeners 类型存入到集合中
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class<?>[] types = new Class[]{SpringApplication.class, String[].class};
return new SpringApplicationRunListeners(logger, this.getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args), this.applicationStartup);
}
- listeners.starting(bootstrapContext, this.mainApplicationClass);循环调用监听starting方法
- .ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);利用 listeners 读取我们配置文件数据到SpringBoot容器中
- Banner printedBanner = this.printBanner(environment);
- context = this.createApplicationContext();创建SpringBoot对应上下文的环境
- this.refreshContext(context);刷新上下文
- this.onRefresh();开始创建我们的tomcat容器
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var10) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
}
this.destroyBeans();
this.cancelRefresh(var10);
throw var10;
} finally {
this.resetCommonCaches();
contextRefresh.end();
}
}
}
- 开始加载SpringMVC
获取spring-boot-configurations下面的META-INF/ spring.factorie所有的类注册到IOC容器中。
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration - this.afterRefresh(context, applicationArguments);定义一个空的模版给其他子类实现重写
- listeners.started(context, timeTakenToStartup);使用广播和回调机制通知监听器已SpringBoot容器启动成功