YAML 是一种以数据为中心的配置格式,Spring Boot 从诞生之初就原生支持它。相比传统的 properties 文件用点号拼接出一长串键名,YAML 用缩进表达层级关系,同一组配置在视觉上聚合在一起,维护起来一目了然。很多初学者在接触 Spring Boot 时直接复制网上的 yml 配置,却因为缩进空格数不对、冒号后少了空格等问题导致项目启动失败,这篇文章就从语法细节到进阶用法,把 YAML 配置完整梳理一遍。

YAML 基础语法与常见陷阱
YAML 的核心规则只有几条:使用缩进表示层级,缩进只能用空格不能用 Tab;键值对用冒号加空格分隔,也就是key: value,冒号后面那个空格是必须的;大小写敏感。看起来简单,但恰恰是这些细节最容易出问题。比如下面这份配置,server 缩进了两个空格,port 又在 server 基础上再缩进两个空格,表示 port 是 server 的子配置项。
server:
port: 8081
servlet:
context-path: /demo
spring:
application:
name: order-service几个高频踩坑点需要特别留意。第一,同一层级不允许不同的缩进空格数,比如 server 下面的 port 缩进两个空格,而 servlet 却缩进三个空格,解析时会直接报错。第二,字符串值如果以特殊字符开头(比如星号、百分号),需要用引号包起来,普通字符串则可写可不写。第三,YAML 会把on、off、true这类词解析为布尔值,如果要作为字符串使用就必须加引号。第四,日期类型推荐写成yyyy-MM-dd HH:mm:ss格式的字符串,交给 Spring 解析,避免各版本解析行为不一致。
另外,YAML 一个文件中允许用三个横杠---分隔多个文档块,配合spring.config.activate.on-profile可以实现单文件多环境配置,这一点后面会详细展开。还需要注意的是,properties 文件和 yml 文件可以同时存在于 classpath 下,此时 properties 的优先级更高,如果两个文件里都配置了同一个键,yml 中的值会被覆盖,排查配置不生效问题时别忘了检查这一点。
常用配置示例:数据源、端口与日志
实际项目中,application.yml 里出现频率最高的是数据源、连接池和日志配置。下面是一份典型的 Spring Boot 数据源配置,使用 Druid 连接池,并通过url中的参数指定时区和编码。可以看到嵌套结构让配置天然分组成块,比 properties 的扁平键值对清爽得多。
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/shop?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: "123456"
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 5
max-active: 20
min-idle: 5
logging:
level:
com.example.mapper: debug
file:
name: logs/app.log除了直接写值,YAML 还支持占位符复用。比如数据库密码在多处引用时,可以先定义一个自定义键,再用${}引用它。这样改一处即可全局生效,减少配置冗余。
app:
secret: abc123
custom:
token: ${app.secret}
name: ${app.name:defaultName}占位符${app.name:defaultName}中的冒号表示默认值,当 app.name 不存在时取 defaultName,这在配置项可能缺失的场景下非常实用。环境变量也能以同样方式注入,例如${MYSQL_HOST}会读取系统环境变量,让容器化部署时无需改动配置文件即可切换数据库地址。
多环境配置与 Profile 激活
开发、测试、生产三个环境各有各的数据库地址和日志级别,把所有配置塞进一个文件显然不合理。Spring Boot 提供了 profile 机制,可以按环境拆分配置。常见做法有两种:一是创建 application-dev.yml、application-test.yml、application-prod.yml 三个文件,然后在主配置文件中指定激活哪个环境;二是直接在一个 yml 文件里用文档块分隔。
spring:
profiles:
active: dev
---
spring:
config:
activate:
on-profile: dev
datasource:
url: jdbc:mysql://127.0.0.1:3306/dev_db
---
spring:
config:
activate:
on-profile: prod
datasource:
url: jdbc:mysql://127.0.0.1:3306/prod_db激活环境的方式不止配置文件一种。启动 jar 包时通过命令行参数指定最灵活:java -jar app.jar --spring.profiles.active=prod,或者设置环境变量SPRING_PROFILES_ACTIVE=prod。多环境部署到不同服务器时,往往不改动打包内容,只在服务器上配环境变量,这样同一个包可以在任意环境运行,这也是 DevOps 实践中的推荐做法。
优先级方面需要注意,命令行参数高于环境变量,环境变量高于配置文件中的 spring.profiles.active 设置。排查配置问题时,可以在项目启动后访问 actuator 的 env 端点,或者临时写个 Controller 输出 Environment 中的属性值,确认当前生效的到底是哪个环境的配置,避免被多份配置文件绕晕。
配置绑定:@ConfigurationProperties 与 @Value 对比
配置写好后,如何在代码里优雅地读取?Spring Boot 提供了两种主流方式。@Value 注解适合读取零散的单个值,直接在字段上标注即可;而 @ConfigurationProperties 适合批量绑定一组有结构的配置到实体类,配合 IDE 还能获得提示和校验支持。
@Component
@ConfigurationProperties(prefix = "app.mail")
public class MailProperties {
private String host;
private Integer port;
private Boolean enable = true;
// 省略 getter 和 setter
}对应的 yml 配置如下,属性名按驼峰自动匹配,host 绑定到 host,enableSsl 也能自动匹配 enable-ssl 的写法,这种松散绑定规则让配置命名不必与字段名严格一致。
app:
mail:
host: smtp.ipipp.com
port: 465
enable-ssl: true两种方式的差异值得展开说说。@Value 不支持松散绑定,配置里的键名必须和注解中的完全一致;不支持复杂类型的批量注入,一个 List 要借助 SpEL 表达式才能解析;但它支持 SpEL,可以写一些动态表达式。@ConfigurationProperties 则支持 JSR303 校验,加上 @Validated 注解并在字段上标注 @NotNull 等规则,项目启动时就能拦截非法配置,把问题暴露在最早阶段。综合来看,结构化的业务配置优先用 @ConfigurationProperties,临时读取一两个简单值时用 @Value 即可。
小结
YAML 在 Spring Boot 中的角色不只是配置文件格式,它配合 profile、占位符和配置绑定机制,构成了完整的外部化配置体系。掌握缩进规则和值类型解析这些基础细节,能避免大部分启动报错;理解多环境的激活顺序与优先级,则能在部署时从容切换。建议新项目统一采用 yml 格式,并为自定义配置建立清晰的层级前缀,后续维护和迁移都会轻松很多。
Spring BootYAML配置application.yml修改时间:2026-09-03 15:51:14