【SpringBoot】深入剖析 Spring Boot 启动过程(附源码与实战)

embedded/2025/3/12 1:27:23/

深入剖析 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);
}

它主要做了如下几件事:

  1. 创建 SpringApplication 实例
  2. 调用 run() 方法,执行核心启动逻辑
  3. 返回 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. 打印 BannerprintBanner(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.propertiesapplication.yml 等配置信息,并决定是否启用 DevTools

3️⃣ 创建 Spring 容器

createApplicationContext() 通过 SpringFactoriesLoader 加载 SpringApplication 配置的 ApplicationContext 实现类(如 AnnotationConfigServletWebServerApplicationContext),然后 prepareContext() 进行配置。

4️⃣ 刷新容器

refreshContext() 最终调用 context.refresh(),完成 Spring 核心的 refresh() 过程,初始化 BeanFactory,注册 Bean 后处理器,完成 AOP、事务等功能的初始化。

5️⃣ 运行 ApplicationRunnerCommandLineRunner

Spring Boot 提供 ApplicationRunnerCommandLineRunner 接口,在 afterRefresh() 方法中执行,可以在应用启动后运行特定代码:

@Component
public class MyRunner implements ApplicationRunner {@Overridepublic 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) {}@Overridepublic void starting() {System.out.println(">>> Spring Boot 正在启动...");}@Overridepublic void environmentPrepared(ConfigurableEnvironment environment) {System.out.println(">>> Environment 已准备:" + environment.getActiveProfiles());}@Overridepublic void contextPrepared(ConfigurableApplicationContext context) {System.out.println(">>> ApplicationContext 已创建...");}@Overridepublic void started(ConfigurableApplicationContext context) {System.out.println(">>> Spring Boot 已启动!");}@Overridepublic void running(ConfigurableApplicationContext context) {System.out.println(">>> Spring Boot 运行中...");}@Overridepublic 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. 总结

  1. Spring Boot 启动的核心入口是 SpringApplication.run(),它完成环境准备、容器创建、事件发布等步骤。
  2. 核心组件包括 SpringApplicationRunListenersEnvironmentApplicationContext,它们协同完成应用初始化。
  3. 我们可以自定义 SpringApplicationRunListener,监听 Spring Boot 启动事件,实现日志记录或其他增强功能。

Spring Boot 的启动过程是一个标准化的“模板方法模式”实现,每一步都可以通过扩展点进行自定义,极大增强了框架的可扩展性。希望本篇文章能帮助你更好地理解 Spring Boot 的启动原理!


📌 你学会了吗? 欢迎在评论区留言交流!🚀


http://www.ppmy.cn/embedded/171895.html

相关文章

‌Visual Studio Code(VS Code)支持的编程语言

‌JavaScript‌&#xff1a;VS Code 原生支持 JavaScript&#xff0c;提供语法高亮、代码折叠、自动补全等功能。推荐使用ESLint和Prettier进行代码格式化和错误检查‌。 ‌TypeScript‌&#xff1a;作为 JavaScript 的超集&#xff0c;TypeScript 在 VS Code 中也得到原生支持…

Spark Shuffle原理浅解析

一、Shuffle的核心定义与作用 Shuffle 是Spark中跨节点数据重分区的过程,通常由宽依赖操作(如groupByKey、join)触发。其核心目的是将相同Key的数据分发到同一个节点,以便进行聚合或连接操作。 重要性: 数据分区:确保后续计算(如Reduce阶段)能按Key正确处理数据。性能…

Nginx环境安装

一、官网地址 Nginx官网&#xff1a;http://nginx.org/ Nginx中文网&#xff1a;https://nginx.p2hp.com/ 二、Nginx版本 mainline version 开发版本stableversion 稳定版本legacy version 历史版本 三、Windows系统安装Nginx 第一步&#xff1a;选择Windows版本&#xff0c;…

做到哪一步才算精通SQL

做到哪一步才算精通SQL-Structured Query Language 数据定义语言 DDL for StructCREATE&#xff1a;用来创建数据库、表、索引等对象ALTER&#xff1a;用来修改已存在的数据库对象DROP&#xff1a;用来删除整个数据库或者数据库中的表TRUNCATE&#xff1a;用来删除表中所有的行…

VScode:运行程序停止后,频繁出现终端进程被终止

VScode里面powershell被迫关闭 bug场景排查原因解决办法 bug场景 系统&#xff1a;Windows IDE&#xff1a;Visual Studio Code 停止运行程序后&#xff0c;按向上箭头想要执行上一步命令&#xff0c;忽然终端页面强行关闭&#xff0c;并报错如下&#xff1a; 终端进程 &quo…

读书笔记 - Spring Boot实战

读书笔记 - Spring Boot实战 第1章 入门Spring Boot精要1. 自动配置2. 起步依赖3. 命令行界面4. Actuator 使用Spring Initializr初始化Spring Boot项目 第2章 运用SpringBootSpringBootApplication配置应用程序属性指定基于功能的依赖覆盖起步依赖引入的传递依赖使用自动配置 …

基于Asp.net的高校迎新管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

C#程序结构及基本组成说明

C# 程序的结构主要由以下几个部分组成,以下是对其结构的详细说明和示例: 1. 基本组成部分 命名空间 (Namespace) 用于组织代码,避免命名冲突。通过 using 引入其他命名空间。 using System; // 引入 System 命名空间类 (Class) C# 是面向对象的语言,所有代码必须定义在类或…