962 字
约 3 分钟
7
S07-B05 · Spring Boot:自动配置与启动流程

适用读者:想知道"为什么不用配 Tomcat"的人。
前置:S07-B04。
实测环境:Spring Boot 3.3.6 / JDK 17(2026-11-05)。
覆盖旧文:2620(210) 981(88) 979(75) 980(68) 962(89) 1741(85) 321(82) 322(29) 1756(49) 1739(126) = 987 点。
覆盖扩展:E-S07-008(自动配置 SPI)、E-S07-009(内嵌容器)。
上一篇:S07-B04 · Spring MVC:一个请求走过哪些组件
下一篇:S07-B06 · Web 层实战。


1. 一句话结论

Spring Boot = Spring + 自动配置(条件装配)+ 内嵌容器 + 约定优于配置。它的核心机制是"用 @Conditional 决定哪些配置类生效"。

实测(启动日志):

Tomcat started on port 19070 (http) with context path '/'
Started App in 8.281 seconds (process running for 10.181)

两个关键信息:容器是内嵌的(不需要外部 Tomcat);启动8–10 秒主要花在"扫描 + 装配 + 启动容器"。


2. 自动配置怎么生效(E-S07-008)

@SpringBootApplication
 ├─ @SpringBootConfiguration
 ├─ @ComponentScan(扫当前包及子包)
 └─ @EnableAutoConfiguration
      └─ 读取 META-INF/spring/...AutoConfiguration.imports(Boot 3)
         → 一堆 @Configuration 类,各自带 @ConditionalOnClass/@ConditionalOnMissingBean
条件注解 含义
@ConditionalOnClass classpath 有某个类才生效(如 DataSource)
@ConditionalOnMissingBean 你没有自己定义时才生效(可覆盖)
@ConditionalOnProperty 配置项满足才生效

"为什么加个 starter 就有一堆 Bean":starter 带来依赖 → 自动配置类因 @ConditionalOnClass 满足而生效 → 创建 Bean。

"怎么覆盖默认行为":自己定义同类型 Bean(@ConditionalOnMissingBean 让位)。


3. 启动流程(A-979/A-980)

① SpringApplication.run()
② 准备 Environment(配置文件、命令行、环境变量)
③ 创建 ApplicationContext(Servlet/Reactive)
④ 加载 BeanDefinition(扫描 + 自动配置)
⑤ refresh():实例化单例、启动内嵌容器、发布事件
⑥ 启动完成(ApplicationReadyEvent)
阶段 可插手点
② EnvironmentPostProcessor、application.yml
⑤ ApplicationListener、SmartLifecycle
⑥ CommandLineRunner / ApplicationRunner

实测启动耗时 8.281s / 9.838s(两次构建);其中 Tomcat 启动在最后一步。


4. 内嵌容器(A-1756,E-S07-009)

问题 答案
为什么不用装 Tomcat 依赖里已有 tomcat-embed-core,SpringApplication 直接启动它
能换吗 能(spring-boot-starter-jetty / undertow,排除 tomcat)
能打 war 吗 能(<packaging>war</packaging> + 外部容器)

实测的构建坑:只引 spring-boot-starter-parent 不够,必须显式声明 spring-boot-maven-plugin,否则:

no main manifest attribute, in target/s07-1.0.0.jar

这是"能编译但跑不起来"的典型——jar 缺少 Main-Class。


5. 配置与 Profile(A-321/A-322)

文件 说明
application.yml 主配置
application-dev.yml 环境覆盖
激活 --spring.profiles.active=dev 或环境变量

.yml vs .properties:yml 有层级、可读性好;properties 更"扁平"、无缩进陷阱。团队选一种即可,别混用。

配置优先级(高→低):命令行 > 环境变量 > application-{profile}.yml > application.yml。


6. 五个误区

误区 真相
"Boot 就是 Spring 加了个启动类" 核心是条件装配
"自动配置不能改" @ConditionalOnMissingBean 允许覆盖
"必须用内嵌 Tomcat" 可换 Jetty/Undertow 或打 war
"加 parent 就能打可执行 jar" 还要声明 repackage 插件
"启动慢是 JVM 的锅" 多半是扫描范围/Bean 数量/自动配置过多

7. 自检

  1. @SpringBootApplication 由哪三个注解组成?
  2. 自动配置靠什么决定"是否生效"?
  3. 怎么覆盖某个自动配置的默认 Bean?
  4. 为什么不用安装 Tomcat?
  5. "no main manifest attribute" 说明缺什么?

8. 下一篇

S07-B06 · Web 层实战:校验、异常、日志、文档、监控

机制讲完,下一篇落地:统一响应结构、全局异常、MDC 链路日志、接口文档与监控。


本篇属于系列《S07 · Spring 框架》。旧文来源:A-2620/981/979/980/962/1741/321/322/1756/1739;扩展点 E-S07-008/009。启动日志与 jar 报错为 Spring Boot 3.3.6 实测。

S07-B05 · Spring Boot:自动配置与启动流程
https://www.clxhxhhr.top/posts/5272/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。