深入剖析 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 的启动原理!
📌 你学会了吗? 欢迎在评论区留言交流!🚀