SpringBoot启动流程(概括)
Spring boot是Spring家族中的一个全新的框架,它用来简化Spring应用程序的创建和开发过程。
特性
1.自动配置:针对很多Spring应用程序和常见的应用功能,Spring boot能自动提供相关配置;:
2.起步依赖:告诉Spring boot需要什么功能,它就能引入需要的依赖库;
3.Actuator:让你能够深入运行中的Spring Boot应用程序,一探Spring boot程序的内部信息;
4.命令行界面:这是Spring Boot的可选特性,主要针对Groovy语言使用。
启动流程大致分为两步一是对primarySources的准备工作二是运行run步骤
public SpringApplication(Class... primarySources) {
this((ResourceLoader)null, primarySources);
}
这边主要做了以下4个步骤:
- 判断当前应用程序的类型NONE、SERVLET、REACTIVE
- 加载所有的初始化容器
- 加载所有的监听器
- 找到程序运行的主类
方法里面调用的构造方法如下:
public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = new HashSet();
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
this.webApplicationType = this.deduceWebApplicationType();
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}
接下来就是run方法:
/**
* Run the Spring application, creating and refreshing a new
* {@link ApplicationContext}.
* @param args the application arguments (usually passed from a Java main method)
* @return a running {@link ApplicationContext}
*/
public ConfigurableApplicationContext run(String... args) {
//第一步:开启计时器
//设置当前任务的id和启动的时间,方便后续的时候
//进行计时的操作
StopWatch stopWatch = new StopWatch();
stopWatch.start();
//设置空值以及异常集合,不是很重要
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
//第二步:配置系统属性java.awt.headless意义不大,可以忽略
configureHeadlessProperty();
//第三步:获取一个EventPublishingRunListeners的对象,此对象会贯穿整个应用程序启动的过程,每次在进行监听器操作的时候都会从中获取具体的监听器
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
//第四步:加载命令行的参数值,解析在命令行中通过--key=value输入的属性值,封装到ApplicationArguments对象中
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//第五步:准备当前的应用环境
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
//第六步:设置系统属性,保证某些bean不会添加到准备的环境中spring.beaninfo.ignore
configureIgnoreBeanInfo(environment);
//第七步:准备banner的打印,就是刚开始运行的图片
Banner printedBanner = printBanner(environment);
//第八步:准备上下文应用对象,根据当前应用程序的类型来判断创建什么格式的上下文对象
context = createApplicationContext();
//第九步:设置异常报告器对象
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
//第十步:设置异常报告器对象 准备当前上下文对象
//1.设置初始化进行执行,向beanfactory中注入了三个postprocessor的对象,后续在自动装配的时候会用到applylnitializers(context);
//2.listeners.contextPrepared(context);
//3.加载很多资源配置,自动装配在此环节完成load(context,sources.toArray(new Object[]);
//4.listeners.contextLoaded(context);
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//第十一步:刷新上下文环境(关键操作),已经在spring的时候会讲到
refreshContext(context);
//第十二步:上下文对象准备好之后的操作,默认什么都不做,方便扩展
afterRefresh(context, applicationArguments);
//第十三步:计时结束,并打印启动程序运行的时长
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
//第十四步:开始所有的监听器对象
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
//第十五步:运行
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
同时附上关于SpringBoot的启动原理图: