本文自己写的(头条也有这篇文章),若有问题,请指正。
大致流程如下:
1. 初始化SpringApplication,从META-INF下的spring.factories读取
ApplicationListener/ApplicationContextInitializer
2.运行SpringApplication的run方法
3.读取项目中环境变量、jvm配置信息、配置文件信息等
4.创建Spring容器对象(ApplicationContext)
5. 利用
ApplicationContextInitializer初始化Spring容器对象,读取启动类
6.调用spring的refresh加载IOC容器、自动配置类,并创建bean、servlet容器等信息
7.springboot会调用很多监听器
8.如果启动时发生异常,则发送ApplicationFailedEvent事件
下面对上述流程进行源码细化分析,首先调用SpringApplication.run启动springboot应用:
@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)
@EnableTransactionManagement(proxyTargetClass = true)
@Import(MyDynamicDataSourceConfig.class)
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
进入run方法后,会进行SpringApplication进行启动,分两大步,第一步初始化SpringApplication,第二步调用run方法:
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}
第一步初始化SpringApplication,new SpringApplication(primarySources)的流程如下(具体方法含义参考注释):
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// 根据classpath下的类,推算当前web应用类型(REACTIVE/SERVLET/NONE)
this.webApplicationType = WebApplicationType.deduceFro