1. 引言
SpringBoot是一个广泛使用的Java框架,旨在简化基于Spring框架的应用程序的开发过程。在这篇文章中,我们将深入探讨SpringBoot应用程序的启动流程,了解其背后的机制。
2. Spring Boot 启动概览
SpringBoot应用程序的启动通常从一个包含 main 方法的类开始,例如:
@SpringBootApplication
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}
这里的SpringApplication.run是启动SpringBoot应用程序的入口。接下来,我们将深入分析这个方法及其调用的各个阶段。
3. SpringApplication 类详解
SpringApplication类是SpringBoot应用程序启动过程的核心类。它负责初始化应用程序的上下文,加载配置,启动嵌入式服务器等。
3.1 SpringApplication构造函数
SpringApplication类有多个构造函数,常用的是接收一个或多个Class<?> 参数的构造函数:
public SpringApplication(Class<?>... primarySources) {this.setInitializers((Collection) this.getSpringFactoriesInstances(ApplicationContextInitializer.class));this.setListeners((Collection) this.getSpringFactoriesInstances(ApplicationListener.class));this.mainApplicationClass = this.deduceMainApplicationClass();
}
这里设置了初始化器和监听器,并推断出主应用程序类。
3.2 run 方法
SpringApplication.run方法是启动SpringBoot应用程序的入口:
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {return (new SpringApplication(primarySources)).run(args);
}
这个方法内部调用了SpringApplication实例的run方法:
public ConfigurableApplicationContext run(String... args) {// 初始化阶段this.configureHeadlessProperty();SpringApplicationRunListeners listeners = this.getRunListeners(args);listeners.starting();// 环境准备阶段ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);this.configureIgnoreBeanInfo(environment);// 上下文创建阶段Banner printedBanner = this.printBanner(environment);ConfigurableApplicationContext context = this.createApplicationContext();this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);// 上下文刷新阶段this.refreshContext(context);this.afterRefresh(context, applicationArguments);listeners.finished(context, null);// 应用程序运行阶段this.callRunners(context, applicationArguments);return context;
}
接下来,我们逐步解析这些方法的具体实现。
4. 启动流程详解
4.1 初始化阶段
在这个阶段,主要是一些基本属性的设置和启动监听器的初始化:
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
configureHeadlessProperty:设置系统属性java.awt.headless,用于处理缺少显示屏、键盘或鼠标的环境。
getRunListeners:获取并初始化SpringApplicationRunListeners,这些监听器在整个启动过程中会监听并响应不同的事件。
4.2 环境准备阶段
准备应用运行的环境,包括配置属性和配置文件等:
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
this.configureIgnoreBeanInfo(environment);
prepareEnvironment:配置并准备环境,调用监听器的environmentPrepared方法。
configureIgnoreBeanInfo:配置是否忽略BeanInfo信息。
4.3 上下文创建阶段
创建并准备 Spring 应用上下文:
ConfigurableApplicationContext context = this.createApplicationContext();
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
createApplicationContext:根据配置创建具体的应用上下文,例如 AnnotationConfigApplicationContext。
prepareContext:准备上下文,加载配置,注册Bean,调用监听器的 contextPrepared 方法。
4.4 上下文刷新阶段
刷新应用上下文,完成 Bean 的初始化和依赖注入:
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
refreshContext:刷新应用上下文,触发 Spring 的生命周期事件。
afterRefresh:刷新后的操作,通常用于自定义逻辑。
4.5 应用程序运行阶段
调用所有实现了CommandLineRunner和ApplicationRunner接口的 Bean:
this.callRunners(context, applicationArguments);
callRunners:遍历并调用所有CommandLineRunner和 ApplicationRunner。
5. 结论
通过深入分析SpringBoot应用程序的启动流程,我们可以更好地理解其内部机制,进而在开发中更好地利用这些机制,提高开发效率和代码质量。在后续的文章中,我们将继续探讨SpringBoot的其他关键特性和实现原理。