深入剖析 Spring Boot 启动过程(附源码与实战)
Spring Boot 以其“开箱即用”的特性深受开发者喜爱,然而,Spring Boot 是如何启动的?它如何做到自动化配置?这背后的原理是什么?本篇文章将从源码出发,剖析 Spring Boot 启动的核心流程,并通过代码实战加深理解。
1. Spring Boot 启动的核心流程
Spring Boot 应用的启动通常从 main 方法开始,例如:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
其中 SpringApplication.run() 是启动的关键入口,我们接下来深入分析其核心流程。
1.1 SpringApplication.run() 过程
源码入口位于 SpringApplication 类的 run() 方法:
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return new SpringApplication(primarySource).run(args);
}
它主要做了如下几件事:
- 创建
SpringApplication实例 - 调用
run()方法,执行核心启动逻辑 - 返回
ConfigurableApplicationContext作为 Spring 容器
进一步分析 run() 方法内部逻辑:
public ConfigurableApplicationContext run(String... args) {
long startTime = System.nanoTime();
// 1. 创建并启动 `SpringApplicationRunListeners`
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
// 2. 构造 `ApplicationArguments`
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 3. 准备 `Environment`
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
// 4. 打印 Banner
printBanner(environment);
// 5. 创建 `ApplicationContext`
ConfigurableApplicationContext context = createApplicationContext();
// 6. 准备 `ApplicationContext`
prepareContext(context, environment, listeners, applicationArguments);
// 7. 刷新 `ApplicationContext`
refreshContext(context);
// 8. 执行 `ApplicationRunner` 和 `CommandLineRunner`
afterRefresh(context, applicationArguments);
// 9. 通知所有监听器,启动完成
listeners.started(context);
listeners.running(context);
return context;
}
1.2 关键步骤详解
1️⃣ SpringApplicationRunListeners
在 getRunListeners(args) 方法中,会加载 META-INF/spring.factories 中的 SpringApplicationRunListener,如 EventPublishingRunListener,用于发布 Spring Boot 启动相关的事件,如 ApplicationStartedEvent。
2️⃣ Environment 准备
prepareEnvironment() 方法用于加载 application.properties 或 application.yml 等配置信息,并决定是否启用 DevTools。
3️⃣ 创建 Spring 容器
createApplicationContext() 通过 SpringFactoriesLoader 加载 SpringApplication 配置的 ApplicationContext 实现类(如 AnnotationConfigServletWebServerApplicationContext),然后 prepareContext() 进行配置。
4️⃣ 刷新容器
refreshContext() 最终调用 context.refresh(),完成 Spring 核心的 refresh() 过程,初始化 BeanFactory,注册 Bean 后处理器,完成 AOP、事务等功能的初始化。
5️⃣ 运行 ApplicationRunner 和 CommandLineRunner
Spring Boot 提供 ApplicationRunner 和 CommandLineRunner 接口,在 afterRefresh() 方法中执行,可以在应用启动后运行特定代码:
@Component
public class MyRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("ApplicationRunner 执行,参数:" + Arrays.toString(args.getSourceArgs()));
}
}
2. 代码实战:自定义 SpringApplicationRunListener
我们可以自定义 SpringApplicationRunListener 来监听 Spring Boot 启动过程,并记录日志。
2.1 创建 MyApplicationRunListener
public class MyApplicationRunListener implements SpringApplicationRunListener {
public MyApplicationRunListener(SpringApplication application, String[] args) {}
@Override
public void starting() {
System.out.println(">>> Spring Boot 正在启动...");
}
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
System.out.println(">>> Environment 已准备:" + environment.getActiveProfiles());
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
System.out.println(">>> ApplicationContext 已创建...");
}
@Override
public void started(ConfigurableApplicationContext context) {
System.out.println(">>> Spring Boot 已启动!");
}
@Override
public void running(ConfigurableApplicationContext context) {
System.out.println(">>> Spring Boot 运行中...");
}
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) {
System.out.println(">>> 启动失败:" + exception.getMessage());
}
}
2.2 配置 META-INF/spring.factories
在 resources/META-INF/spring.factories 文件中,添加:
org.springframework.boot.SpringApplicationRunListener=com.example.listener.MyApplicationRunListener
这样,Spring Boot 启动时,就会自动加载 MyApplicationRunListener,输出日志。
3. 总结
- Spring Boot 启动的核心入口是
SpringApplication.run(),它完成环境准备、容器创建、事件发布等步骤。 - 核心组件包括
SpringApplicationRunListeners、Environment、ApplicationContext,它们协同完成应用初始化。 - 我们可以自定义
SpringApplicationRunListener,监听 Spring Boot 启动事件,实现日志记录或其他增强功能。
Spring Boot 的启动过程是一个标准化的“模板方法模式”实现,每一步都可以通过扩展点进行自定义,极大增强了框架的可扩展性。希望本篇文章能帮助你更好地理解 Spring Boot 的启动原理!
📌 你学会了吗? 欢迎在评论区留言交流!🚀