当前位置: 首页 > article >正文

Spring Boot 启动流程解析及重点源码

文章目录

    • 引言
    • Spring Boot 启动类分析
      • 1、@SpringBootApplication 注解
      • 2、 SpringApplication.run() 方法
      • 3、Spring Boot 启动流程详解
        • 3.1 创建 SpringApplication 实例
        • 3.2 准备环境(Environment)
        • 3.3 执行 ApplicationListeners
        • 3.4 刷新应用上下文(ApplicationContext)
        • 3.5 启动嵌入式容器
        • 3.6 触发 ApplicationReadyEvent
    • 总结

引言

Spring Boot 是一个用于创建独立的、生产级的基于 Spring 框架的应用程序的框架。本文将深入探讨 Spring Boot 应用程序的启动流程,并提供关键步骤中的源码分析,帮助我们更好地理解其内部机制。

Spring Boot 启动类分析

1、@SpringBootApplication 注解

通常,一个 Spring Boot 应用程序的入口点是一个带有 @SpringBootApplication 注解的主类。这个注解是以下三个注解的组合:

@Configuration: 标识该类为配置类。
@EnableAutoConfiguration: 开启自动配置功能,根据 classpath 中的依赖自动配置应用程序。
@ComponentScan: 自动扫描并注册组件(如 @Component, @Service, @Repository 等)。
@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

在这里插入图片描述

2、 SpringApplication.run() 方法

SpringApplication.run() 方法是启动 Spring Boot 应用的核心方法。它会执行以下步骤:
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
    return run(new Class[]{primarySource}, args);
}

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
    // 创建 SpringApplication 实例
    return (new SpringApplication(primarySources)).run(args);
}

3、Spring Boot 启动流程详解

3.1 创建 SpringApplication 实例

当调用 SpringApplication.run() 方法时,首先会创建一个 SpringApplication 实例。这个实例负责管理整个启动过程,并提供了一些配置选项,例如设置 Banner、日志级别等。

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    this.resourceLoader = resourceLoader;
    Assert.notNull(primarySources, "PrimarySources must not be null");
    this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    setInitializers((Collection) getSpringFactoriesInstances(
        ApplicationContextInitializer.class,
        new Class<?>[] { ConfigurableApplicationContext.class }));
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = deduceMainApplicationClass();
}
3.2 准备环境(Environment)

接下来,Spring Boot 会准备环境,主要包括加载默认配置(如 application.properties 或 application.yml),解析命令行参数和系统属性,初始化 Environment 对象。

protected void prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
    // 加载默认配置
    ConfigurableEnvironment environment = getOrCreateEnvironment();
    configureEnvironment(environment, applicationArguments.getSourceArgs());
    ConfigurationPropertySources.attach(environment);
    listeners.environmentPrepared(this.getApplicationContext(), environment);
    bindToContext(environment);
}
3.3 执行 ApplicationListeners

在启动过程中,Spring Boot 会触发一系列事件,并允许开发者通过实现 ApplicationListener 接口来监听这些事件。

private void callRunners(ApplicationContext context, ApplicationArguments args) {
    List<ApplicationRunner> runners = new ArrayList<>();
    List<CommandLineRunner> commandLineRunners = new ArrayList<>();
    addListeners(runners, context);
    addListeners(commandLineRunners, context);
    AnnotationAwareOrderComparator.sort(runners);
    AnnotationAwareOrderComparator.sort(commandLineRunners);
    runRunners(runners, args);
    runRunners(commandLineRunners, args);
}
3.4 刷新应用上下文(ApplicationContext)

这是启动过程中最重要的一步,主要任务包括初始化所有单例 Bean,调用 BeanFactoryPostProcessor 和 BeanPostProcessor,发布 ContextRefreshedEvent 事件。

@Override
protected void refreshContext(ConfigurableApplicationContext context) {
    super.refreshContext(context);
    context.publishEvent(new ApplicationContextInitializedEvent(this, context));
}

@Override
protected void finishRefresh(Context context, ConfigurableApplicationContext applicationContext) {
    super.finishRefresh(context, applicationContext);
    context.publishEvent(new ApplicationReadyEvent(this, context));
}
3.5 启动嵌入式容器

如果应用程序中包含嵌入式容器(如 Tomcat、Jetty 或 Undertow),则在此步骤启动容器。Spring Boot 会根据配置自动选择合适的容器,并将其绑定到指定端口。

private void createAndStartWebServer(ConfigurableApplicationContext context) {
    WebServer webServer = getWebServerFactory().getWebServer(getWebServerServletWebContainerFactory()::getTomcatConnectorCustomizers);
    try {
        webServer.start();
    } catch (Throwable ex) {
        throw new IllegalStateException("Failed to start server", ex);
    }
}
3.6 触发 ApplicationReadyEvent

最后,当所有准备工作完成后,Spring Boot 会发布 ApplicationReadyEvent 事件,表明应用程序已经完全启动并可以接受外部请求。

context.publishEvent(new ApplicationReadyEvent(this, context));

总结

综上所述,我们详细解析了 Spring Boot 应用程序的启动流程,并提供了关键步骤中的源码分析。了解这一过程不仅有助于我们更好地掌握 Spring Boot 的工作原理。


http://www.kler.cn/a/511781.html

相关文章:

  • 在 Babylon.js 中使用 Gizmo:交互式 3D 操作工具
  • Spring Security 6.X + JWT + RBAC 权限管理实战教程(上)
  • 【JavaEE】Spring(1)
  • Vue 3 自定义 Hook:实现页面数据刷新与滚动位置还原
  • 基于springboot的口腔管理平台
  • 双向耦合粒子追踪稳态求解器找到未定义的值?
  • AI监管新思路:从规模导向迈向全面框架
  • 第7章:Python TDD测试Franc对象乘法功能
  • SQL刷题快速入门(三)
  • AI时代的前端主流业务应用发展趋势
  • 使用 HTML 开发 Portal 页全解析
  • 1.简单的爬虫
  • LeetCode 第2815题:数组中的最大数对和
  • 有效的数独
  • 基于深度学习的微出血自动检测及解剖尺度定位|文献速递-视觉大模型医疗图像应用
  • 《鸿蒙Next应用商店:人工智能开启智能推荐与运营新时代》
  • 学习记录之原型,原型链
  • SDL2:PC端编译使用 -- SDL2多媒体库使用音频实例
  • 【Vscode】Vscode不能执行vue脚本的原因及解决方法
  • 2024年度数据科学与机器学习技术总结
  • Java 中求两个 List集合的交集元素
  • MECD+: 视频推理中事件级因果图推理--VLM长视频因果推理
  • Windows11电脑总是一闪一闪的,黑一下亮一些怎么解决
  • node.js 文件操作
  • 解决MAC安装软件时提示“xxx.app 显示已损坏”的方法
  • 抽奖系统(4——活动模块)