Spring boot最大的好处就是遵从了java约定大于配置不用面对一大堆的配置文件,spring boot是根据你用的包来决定提供什么配置。
springBoot的启动可以分为两个部分,第一部分:SpringApplication的实例化;第二部分:调用该实例运行run方法(springboot初始化)。
1、SpringApplication的实例化
1.1 判断是否为webEnvironment
private void initialize(Object[] sources) {
if (sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));
}
//判定是否为webEnvironment
this.webEnvironment = deduceWebEnvironment();
//使用SpringFactoriesLoader在JAR包中META-INF/spring.factories文件中,查找key为ApplicationContextInitializer对应的class,
//并实例化加载所有可用的ApplicationContextInitializer
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
//使用SpringFactoriesLoader在JAR包中META-INF/spring.factories文件中,查找key为ApplicationListener对应的class,
//并实例化加载所有可用的ApplicationListener
setListeners((Collection)
getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
1.2 实例化并加载所有可以加载的ApplicationContextInitializer
ApplicationContextInitializer:当springboot上下文Context初始化完成后会调用
1.3 实例化并加载所有可以加载的监听器ApplicationListener
ApplicationListener:当springboot启动时事件change后都会触发
image.png2、调用该实例运行run方法。
spring boot 初始化内容还是很多的,但是总结起来就四点:
- 2.1 通过SpringFactoriesLoader获取所有的SpringApplicationRunListeners(其实内部只有一个EventPublishingRunListener),调用它们的started()方法,
发布/广播 Springboot启动事件(ApplicationStartingEvent)
也就是说,把springboot启动事件封装成SpringApplicationEvent事件,然后广播出去给SpringApplication中的所有listeners
//org.springframework.boot.context.event.EventPublishingRunListener#running
@Override
public void starting() {
this.initialMulticaster.multicastEvent(
new ApplicationStartingEvent(this.application, this.args));
}
- 2.2 加载环境变量,环境变量包括system environment、classpath environment、application environment(也就是我们自定义的application.properties配置文件),并发布ApplicationEnvironmentPreparedEvent事件
-
2.3 创建ApplicationContext
对ApplicationContext设置环境变量;
配置属性ResourceLoader和ClassLoader属性;
遍历继承1.2步骤中获取的所有继承ApplicationContextInitializer接口的类,循环调用initialize()初始化方法;
发布ApplicationPreparedEvent事件; -
2.4 刷新应用上下文ApplicationContext
这里是ApplicationContext真正开始初始化容器和创建bean的阶段,其中bean的整个生命周期可以从这一步骤看出来;Spring Framework中的所有ApplicationContext实现都直接或间接继承自AbstracttApplicationContext,它的refresh方法描述了整个上下文的初始化逻辑。
2.4.1:准备更新上下文时的预备工作;
2.4.2:获取上下文的内部BeanFactory;
2.4.3:对BeanFactory做些预备工作;
2.4.4:对BeanFactory进行预处理;
2.4.5:执行容器中的BeanFactoryPostProcessor;
2.4.6:注册BeanPostProcessor;
BeanPostProcessor:Bean生命周期的钩子,允许用户对实例化后的Bean进行操作
2.4.7:初始化MessageSource(国际化相关)//忽略;
2.4.8:初始化容器事件广播器(用来发布事件);
2.4.9:初始化一些特殊的Bean;
2.4.10:将所有监听器注册到前两步创建的事件广播器中;
2.4.11:结束BeanFactory的初始化工作;
这一步主要用来将所有的单例BeanDefinition实例化
2.4.12:afterRefresh(上下文刷新完毕);
即,初始化BeanFactory,加载bean,启动内置web容器;
发布ContextRefreshedEvent事件;
//AbstractApplicationContext的refresh方法
synchronized (this.startupShutdownMonitor) {
prepareRefresh();//(1)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//(2)
prepareBeanFactory(beanFactory);//(3)
try {
postProcessBeanFactory(beanFactory);//(4)
invokeBeanFactoryPostProcessors(beanFactory);//(5)
registerBeanPostProcessors(beanFactory);//(6)
initMessageSource();//(7)
initApplicationEventMulticaster();//(8)
onRefresh();//(9)
registerListeners();//(10)
finishBeanFactoryInitialization(beanFactory);//(11)
finishRefresh();//(12)
}catch (BeansException ex) {
//。。。。。。
}
finally {
resetCommonCaches();
}
}
-
2.5 发布/广播 ApplicationStartedEvent事件
-
2.6 发布/广播 ApplicationReadyEvent 事件
-
2.7 启动完成
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
//2.1 获取SpringApplicationRunListeners
SpringApplicationRunListeners listeners = getRunListeners(args);
// 广播/发布 SpringApplicationEvent事件
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
//2.2 加载环境变量
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
//2.3 创建ApplicationContext
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(
SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
//2.4 刷新上下文ApplicationContext
refreshContext(context);
// 发布ContextRefreshedEvent事件;
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
//2.5 发布/广播 ApplicationStartedEvent事件
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
//2.6 发布/广播 ApplicationReadyEvent 事件
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
image.png
网友评论