SpringBoot启动配置原理
Starter启动器
SpringBoot的一大优势是Starter由于SpringBoot有很多开箱即用的Starter依赖,使的我们开发变得简单,我们不需要过多的关注框架的配置
可以认为Starter是一种服务一一使得使用某个功能的开发者不需要关注各种依赖库的处理,不需要具体的配置信息,由SpringBoot自动通过classpath路径下的类发现需要的Bean,并注入bean,
@SpringBootApplication
是由:@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
三个注解组成的
@SpringBootConfiguration:是对配置的说明注解,封装了注解@Configuration
@EnableAutoConfiguration:自动注入配置的注解
由:@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})注解组成
功能是:基于已添加的依赖项,猜”你要如何使用spring相关的配置
@ComponentScan:注解的功能是自动扫描组件,默认扫描所在类的同级类和同
级目录下的所有类,相当于Spring xml配置文件中的context:component-scan
所以@SpringBootApplication:功能是:声明是配置类 自动注入配置 自动扫描包
执行过程逻辑:
- 创建了SpringApplicationContext实例 执行run方法
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return (new SpringApplication(primarySources)).run(args);
} - 创建的时候执行了
加载主配置,确定web应用类型等
this.resourceLoader = resourceLoader;
在springFactoriesLoader类中的loadSpringFactories方法中加载文件
META-INF/spring.factories
查找主程序的main函数
this.mainApplicationClass = this.deduceMainApplicationClass();
Run方法的执行过程
public ConfigurableApplicationContext run(String... args) {
//计时器
StopWatch stopWatch = new StopWatch();
stopWatch.start();
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
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);
stopWatch.stop();
//计时结束, 启动完成
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, listeners);
throw new IllegalStateException(var10);
}