public static void main(String[] args) {
SpringApplication.run(XXXApplication.class, args);
}
public ConfigurableApplicationContext run(String... args) {
// 记录程序运行时间
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// 声明 ApplicationContext
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
// 设置 java.awt.headless 系统属性为 true - 没有图形化界面
this.configureHeadlessProperty();
// 第一步:获取并启动监听器
// 从 META-INF/spring.factories 中获取监听器
SpringApplicationRunListeners listeners = this.getRunListeners(args);
// 发布事件——“容器开始启动”
listeners.starting();
Collection exceptionReporters;
try {
// 第二步:构造 ApplicationContext 环境
// 配置计算机环境,Java 环境,Spring 运行环境,配置Spring 项目 Profiles(SpringBoot 的 application.properties/yml)等等。
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
// 处理需要忽略的 Bean
this.configureIgnoreBeanInfo(environment);
// 打印 banner
Banner printedBanner = this.printBanner(environment);
// 第三步:初始化 ApplicationContext
context = this.createApplicationContext();
// 准备异常报告器
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
// 第四步:ApplicationContext 的前置处理
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// 第五步:刷新 ApplicationContext
// IoC 容器的初始化过程。
// 5.1 Resource 定位(包扫描)
// 5.2 BeanDefinition 的载入(加载 basePackage,判断 @Component 注解,存在即是 BeanDefinition)
// 5.3 注册 BeanDefinition(在 IoC 容器中将 BeanDefinition 注入到一个 ConcurrentHashMap 中)
this.refreshContext(context);
// 第六步:ApplicationContext 的后置处理
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, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
Spring Boot的启动流程主要分为以下几个步骤:
-
初始化Spring应用上下文: 首先,Spring Boot应用会通过
SpringApplication.run()
方法开始启动。这一步主要是创建和配置Spring的应用上下文(ApplicationContext)。 -
创建SpringApplication对象: 在调用
run()
方法之前,首先会创建一个SpringApplication
对象,这一步会加载Spring Boot的各种配置,比如自动配置、属性文件(application.properties或application.yml)中的配置等。 -
运行监听器和初始化器:在SpringApplication准备启动的过程中,它会运行一系列的监听器(Listeners)和初始化器(Initializers)。这些可以用来做一些应用启动前的准备工作。
-
加载Spring Bean定义: 接下来,Spring Boot会加载应用中所有的Spring Bean定义。这包括你自己定义的Bean,和Spring Boot自动配置提供的Bean。
-
自动配置: Spring Boot强大的地方在于它的自动配置功能。它会根据你添加到项目中的依赖,自动配置你需要的组件。比如,如果你添加了Spring Boot的Web依赖,Spring Boot会自动配置Tomcat和Spring MVC。
-
刷新应用上下文: 在所有的Bean定义加载完成后,Spring Boot会刷新应用上下文,这个过程中,所有的Bean都会被创建,并且按照依赖注入的方式组装起来。
-
启动内嵌的Web服务器(如果有的话): 如果你的应用是一个Web应用,Spring Boot会启动一个内嵌的Web服务器(默认是Tomcat),并且将你的应用部署上去。
-
应用启动完成: 最后,Spring Boot会运行所有的CommandLineRunner和ApplicationRunner接口,这时候你的应用就算启动完成了。