Spring Boot 是由 Pivotal 团队提供的全新框架,用来简化新 Spring 应用的初始搭建以及开发过程。 使用版本:2.3.0
Spring Boot特点:
1、降低开发复杂度
2、开箱即用,提过了各种默认配置简化项目配置
3、内嵌web容器
核心注解:
@SpringBootApplication 由以下三种组成:
@SpringBootConfiguration:配置文件
@EnableAutoConfiguration:打开自动配置功能
@ComponentScan:spring组件扫描
在读源码之前需要理解一个概念什么是SPI?
SPI ,全称为 Service Provider Interface,是一种服务发现机制。它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类。
Spring Boot启动流程
1、创建SpringApplication对象,通过SPI机制加载applicationContextInitializer
2、调用run方法获取并启动监听器,准备环境environment,加载应用上下文applicationContext
3、创建spring容器,刷新容器,实例化bean
源码分析
1、初始化SpringAppliction时会区分当前应用程序是哪种环境:REACTIVE|NONE|SERVLET
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
//设置servlet环境
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//获取ApplicationContextInitializer,首次加载META-INF/spring.factories中的类的名称
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
//获取监听器,从spring.factories文件读取ApplicationListener类并初始化监听器对象
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
2、调用run方法,获取并启动监听器,准备环境environment,加载应用上下文applicationContext
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
//获取并启动监听器
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//创建容器环境
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
//创建应用程序上下文
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
//准备容器
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//刷新容器
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);
}
--------
return context;
}