请描述 Spring Boot 的启动流程,包括 SpringApplication 的初始化和 run 方法的核心步骤。

Spring Boot 启动流程详解

Spring Boot 是一个用于简化 Spring 应用程序开发的框架,它提供了一种快速的方式来创建独立的、生产级别的 Spring 应用。它的启动流程相对复杂,但可以总结为几个关键步骤。在这篇文章中,我们将深入探讨 Spring Boot 的启动流程,特别是 SpringApplication 的初始化和 run 方法的核心步骤。

一、SpringApplication 类介绍

SpringApplication 是 Spring Boot 应用程序的核心类。它负责引导和启动应用程序,并处理各种配置和设置。我们可以通过 SpringApplication.run() 方法来启动我们的 Spring Boot 应用。

二、启动流程概述
  1. 创建 SpringApplication 实例:

    • 通常在 main 方法中,我们会创建 SpringApplication 的实例并调用 run 方法。
  2. 准备环境:

    • prepareEnvironment 方法用于准备应用环境(ConfigurableEnvironment)。
  3. 创建应用上下文:

    • createApplicationContext 方法用于创建 Spring 应用上下文。
  4. 加载资源:

    • load 方法用于加载应用的配置和资源。
  5. 注册生命周期监听器:

    • registerListeners 方法用于注册监听器。
  6. 进行自动装配:

    • 通过 refreshContext 方法刷新应用上下文,进行自动装配。
  7. 运行 CommandLineRunner 和 ApplicationRunner:

    • 通过 callRunners 方法执行实现了 CommandLineRunner 和 ApplicationRunner 的实例。
三、核心代码示例

接下来,我们通过 Java 代码来演示以上的过程。

java 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(MyApplication.class);
        application.run(args);
    }
}

在 main 方法中,我们创建了一个 SpringApplication 实例,并调用 run 方法开始启动应用程序。下面,我们将对 run 方法内部的关键步骤进行深入分析。

java 复制代码
public ConfigurableApplicationContext run(String... args) {
    // Step 1: 准备环境
    ApplicationContextInitializer<?>[] initializers = getInitializers();
    ConfigurableEnvironment environment = prepareEnvironment(initializers);
    
    // Step 2: 创建 ApplicationContext
    ConfigurableApplicationContext context = createApplicationContext();
    context.setEnvironment(environment);
    
    // Step 3: 注册监听器
    registerListeners(context);
    
    // Step 4: 加载应用配置
    prepareContext(context, environment, initializers);
    
    // Step 5: 刷新上下文
    refreshContext(context);
    
    // Step 6: 执行命令行和应用运行器
    callRunners(context, args);
    
    return context;
}

四、详细流程步骤解析

  1. 准备环境 (prepareEnvironment):

    • 该步骤会读取配置文件(如 application.yml, application.properties)并初始化环境。
    java 复制代码
    protected ConfigurableEnvironment prepareEnvironment(ApplicationContextInitializer<?>[] initializers) {
        ConfigurableEnvironment environment = new StandardEnvironment();
        // 额外的环境配置逻辑
        return environment;
    }
  2. 创建应用上下文 (createApplicationContext):

    • 选择合适的上下文类型(如 AnnotationConfigApplicationContext 或 ServletWebApplicationContext)并创建它。
    java 复制代码
    protected ConfigurableApplicationContext createApplicationContext() {
        return new AnnotationConfigApplicationContext();
    }
  3. 注册监听器 (registerListeners):

    • 在应用上下文中注册所有的 ApplicationListener。
    java 复制代码
    protected void registerListeners(ConfigurableApplicationContext context) {
        // 注册自定义的 ApplicationListener
    }
  4. 加载配置 (prepareContext):

    • 在这一阶段,应用的主要配置文件被加载,bean 的定义被解析并准备到上下文中。
    java 复制代码
    protected void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, ApplicationContextInitializer<?>[] initializers) {
        // 加载 bean 定义等
    }
  5. 刷新上文 (refreshContext):

    • 在应用上下文刷新过程中,Spring 会加载所有的 bean 并执行相应的初始化。
    java 复制代码
    protected void refreshContext(ConfigurableApplicationContext context) {
        context.refresh();
    }
  6. 调用运行器 (callRunners):

    • Spring Boot 会查找实现了 CommandLineRunner 和 ApplicationRunner 的 bean,并调用它们的 run 方法。
    java 复制代码
    protected void callRunners(ConfigurableApplicationContext context, String[] args) {
        for (CommandLineRunner runner : context.getBeansOfType(CommandLineRunner.class).values()) {
            runner.run(args);
        }
    }

五、最后总结下哈

Spring Boot 的启动流程通过 SpringApplication 类极大地简化了 Spring 应用的初始化过程。上述的各个步骤为我们提供了清晰的框架结构,使得开发者能够快速上手并构建出功能强大的应用程序。Spring Boot 封装了许多复杂的逻辑,使得开发者可以更加专注于业务逻辑的开发,而不必过多关注底层的配置细节。理解这些流程有助于我们在遇到问题时能够更有效地调试与排错。

相关推荐
星恒随风12 小时前
MySQL 从零入门(六):复合查询详解——多表查询、自连接、子查询与 UNION
linux·服务器·数据库·mysql
文丑颜不良啊13 小时前
LeetCode2821~2840题目解析
java·leetcode
无奈笑天下13 小时前
银河麒麟上lsblk命令教程详解
linux·运维·服务器·数据库
apcipot_rain13 小时前
C++转Java日记(10)
java·开发语言
简 洁 冬冬14 小时前
泛型方法写法全面辨析:从「能编译」到「能跑」到「能用」
java·泛型
LGL6030A14 小时前
Java学习历程31——初识Spring Boot
java·spring boot·学习
xiaoye-duck14 小时前
《C++ 项目:手写大模型接入 SDK》会话模块整合:内存 SessionManager 与 DataManager 持久化联动
开发语言·数据库·c++·语言模型
AllData公司负责人15 小时前
AI大模型数据开发底座系列说明书:AllData集成DB-GPT开源项目建设 AI 多模态分析底座,涵盖模态解析/智能大屏/MCP 扩展!
大数据·数据库·人工智能·gpt·数据采集·数据接入·模态解析
2601_9679873716 小时前
Sqlite参考手册
数据库·python·sqlite·api·教程
阿达和自己16 小时前
springboot学习-springboot引入MyBatis-Plus
spring boot·学习·mybatis