跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Spring Boot 启动引导类:命名约定与底层真相

Spring Boot 启动引导类并非强制名为 Application,本质是带 @SpringBootApplication 注解的配置类。核心在于该组合注解及 SpringApplication.run() 流程。Jar 包启动时实际入口为 JarLauncher,通过反射调用业务主类。理解这些有助于掌握自动配置与启动机制。

XiaoPingzi发布于 2026/3/24更新于 2026/7/525 浏览

1. 引导类的'名'与'实':为什么大家都叫 Application?

Spring Boot 提倡'约定优于配置'的理念。XXXApplication 这个命名方式,本质上是官方文档和绝大多数教程为了统一、规范和易于识别而推广的一种约定。它就像是一个显眼的'入口'路牌,告诉所有开发者:'嘿,项目的起点就在这里!'

所以,回答你的第一个问题:'真的是 XXApplication 吗?'——在约定上,是的;但在语法上,不是。 它的真实身份,是一个被 @SpringBootApplication 注解标记的、包含 main 方法的普通 Java 类。

2. 拆解引导类的'灵魂':@SpringBootApplication

引导类的强大,并非源自它的名字,而是它头顶的那个神奇的注解——@SpringBootApplication。这个注解本身并不复杂,但它是一个'三合一'的组合注解,是开启 Spring Boot 世界的钥匙。

// 一个典型的 Spring Boot 引导类
@SpringBootApplication
public class MyAwesomeApp {
    public static void main(String[] args) {
        SpringApplication.run(MyAwesomeApp.class, args);
    }
}

让我们一层层剥开 @SpringBootApplication 的外衣:

  • @SpringBootConfiguration:它本身又是一个 @Configuration 注解的'马甲'。这意味着,我们的引导类本身就是一个配置类。你可以在这个类里通过 @Bean 注解向 Spring 容器注册额外的 Bean。
  • @ComponentScan:这就是**'组件扫描'注解。它的默认扫描范围是引导类所在包及其所有子包**。这就是为什么我们通常建议将引导类放在项目的根目录下,比如 com.example.myproject,这样它就能自动扫描到 com.example.myproject.controller、com.example.myproject.service 等子包下的 @Controller、@Service 等组件。
  • @EnableAutoConfiguration:这是整个 Spring Boot 框架的灵魂所在,负责开启自动配置。它会根据你在项目类路径中添加的依赖(比如 spring-boot-starter-web),自动推断并配置你需要的 Bean。例如,你添加了 web starter,它就会自动帮你配置好 DispatcherServlet 和内嵌的 Tomcat 服务器。

3. 深度剖析:SpringApplication.run() 里到底发生了什么?

引导类的 main 方法只做了一件事:委托给 SpringApplication.run() 静态方法。但这一行代码背后,是一套极其精巧的启动流程。整个过程可以分为两大阶段:初始化 和 运行。

3.1 初始化阶段:准备舞台

当调用 run 方法时,会先创建一个 SpringApplication 实例。在这个构造函数中,Spring Boot 会完成一系列'侦查'工作:

  1. 推断应用类型:检查类路径下是存在 DispatcherServlet(传统 Servlet)还是 DispatcherHandler(WebFlux),从而确定应用类型是响应式 Web 还是 Servlet Web,抑或是非 Web 应用。
  2. 加载初始化器:从 META-INF/spring.factories 文件中加载所有配置的 ApplicationContextInitializer。这些初始化器用于在 Spring 容器刷新前对其进行定制。
  3. 加载监听器:同样从 spring.factories 中加载所有配置的 ApplicationListener。这些监听器会监听启动过程中的不同阶段事件,并执行相应动作。
  4. 推断主启动类:通过堆栈信息找到含有 main 方法的类,也就是我们的引导类。
3.2 运行阶段:正式开演

初始化完成后,真正的 run() 逻辑开始执行,整个过程充满了事件驱动。

  • ApplicationStartingEvent:发布应用启动事件。
  • 准备环境 prepareEnvironment():创建 Environment 对象,并加载系统环境变量、JVM 参数以及最重要的 application.properties/yml 配置文件。完成后发布 ApplicationEnvironmentPreparedEvent。
  • 创建上下文 createApplicationContext():根据初始化阶段推断的应用类型,创建对应的 ApplicationContext(IoC 容器)。例如,对于 Servlet Web 应用,会创建 AnnotationConfigServletWebServerApplicationContext。
  • 准备上下文 prepareContext():将 Environment 绑定到上下文,执行所有已加载的 ApplicationContextInitializer,并通过 @ComponentScan 将引导类本身作为一个配置源,将其 Bean 定义加载到容器中。之后发布 ApplicationPreparedEvent。
  • 刷新上下文 refreshContext():这是 Spring 框架最核心的方法。它会完成所有 Bean 的实例化、依赖注入、初始化,以及最重要的——触发自动配置。Tomcat 等内嵌 Web 服务器也是在此步骤中启动的。
  • 启动后动作 afterRefresh():执行所有实现了 ApplicationRunner 和 CommandLineRunner 接口的回调类,用于执行启动后的初始化任务。
  • ApplicationReadyEvent:发布应用已准备就绪事件,应用正式对外提供服务。

4. 进阶探索:引导类还可以这样玩

除了最简单的 SpringApplication.run(),我们还可以通过创建和定制 SpringApplication 对象来实现更精细的控制。

@SpringBootApplication
public class CustomizedApp {
    public static void main(String[] args) {
        // SpringApplication app = new SpringApplication(CustomizedApp.class);
        SpringApplication app = new SpringApplication();
        app.setPrimarySources(Set.of(CustomizedApp.class));
        app.setBannerMode(Banner.Mode.OFF); // 关闭 Banner
        app.setDefaultProperties(Collections.singletonMap("server.port", "8081")); // 设置默认端口
        // 添加自定义监听器
        app.addListeners(new MyApplicationListener());
        ConfigurableApplicationContext context = app.run(args);
        // ... 可以获取 context 做一些事情
    }
}

5. 终极揭秘:Jar 包启动的'障眼法'

当我们把 Spring Boot 项目打成可执行 Jar 包并运行(java -jar myapp.jar)时,引导类的角色变得更加有趣。你可能会想,我明明设置了 MyAwesomeApp 作为主类,为什么启动时还能看到 Spring Boot 的 Banner?

答案是,真正的'引导'另有其人。Spring Boot 的 Jar 包结构是特殊的,它的 META-INF/MANIFEST.MF 文件里定义了真实的入口:

Main-Class: org.springframework.boot.loader.launch.JarLauncher
Start-Class: com.example.myproject.MyAwesomeApp
  • Main-Class:这里配置的是 JarLauncher,它是 Spring Boot 自己提供的引导程序。它的工作是创建自定义的类加载器,从 Jar 包内部的 BOOT-INF/lib 目录下加载所有依赖的 Jar 包。
  • Start-Class:这里才指向我们编写的引导类 MyAwesomeApp。JarLauncher 在准备好类加载器后,会通过反射调用 MyAwesomeApp 的 main 方法,从而正式启动我们的 Spring Boot 应用。

所以,从物理 Jar 包层面看,真正的'引导类'是 JarLauncher;而从业务逻辑层面看,MyAwesomeApp 仍然是当之无愧的'启动引导类'。这是一种巧妙的分层设计。

总结

现在我们可以清晰地回答你的问题了:

  1. 命名约定:XXApplication 是官方推荐的命名习惯,但不是强制规定。
  2. 本质核心:引导类的本质是一个被 @SpringBootApplication 注解标记的配置类,它作为组件扫描和自动配置的起点。
  3. 启动原理:引导类通过 SpringApplication.run() 触发一系列复杂的初始化、事件发布和容器刷新流程,最终启动内嵌服务器,完成应用自举。
  4. 终极真相:在打包成可执行 Jar 后,物理上的引导类是 JarLauncher,它负责创建环境并调用我们定义的业务引导类。

目录

  1. 1. 引导类的“名”与“实”:为什么大家都叫 Application?
  2. 2. 拆解引导类的“灵魂”:@SpringBootApplication
  3. 3. 深度剖析:SpringApplication.run() 里到底发生了什么?
  4. 3.1 初始化阶段:准备舞台
  5. 3.2 运行阶段:正式开演
  6. 4. 进阶探索:引导类还可以这样玩
  7. 5. 终极揭秘:Jar 包启动的“障眼法”
  8. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 深入理解 C++ 异常机制
  • 前端程序员转行大模型开发指南
  • AR 眼镜光学镜头设计实例与核心技巧解析
  • FPGA 实现 CAN 总线原理与 Verilog 代码详解
  • 大模型 + 数据分析产品打造指南:核心步骤与成功策略
  • 鸿蒙分布式智能办公应用架构设计与性能优化
  • 实时数据处理:Kafka与Python构建高可靠流处理系统
  • 大模型 AI 产品经理学习路线:从基础到实战
  • Python 实现 Markdown 转 Word(docx)文档转换方案
  • Linux 系统安装 Microsoft Edge 浏览器步骤指南
  • 无人机航拍图像处理:目标跟踪与场景重建
  • EpicDesigner Vue3 拖拽式低代码设计器快速上手
  • C++ string 类入门与实现详解
  • 嵌入式C语言文件操作IO读写面试题及参考答案
  • 使用 Web Scraper 插件抓取知乎评论数据实战
  • CentOS 7.2 环境下 Nginx 的 Yum 安装指南
  • 前端首屏全链路性能优化实战:从诊断到落地
  • FPGA 嵌入式块存储器 RAM:原理与实现
  • Python Web 开发:WSGI、uWSGI 与 uwsgi 协议详解
  • VLAC:机器人精准完成任务的 AI 评价新模型

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online