1. 简介
YAML 是一种对人类友好的配置文件格式。在 Spring Boot 项目中,我们为何更倾向于使用 YAML 而非传统的 .properties
文件?除了更佳的可读性、减少重复配置外,YAML 还特别适合实现“配置即代码(Configuration as Code)”,这在 DevOps 流程中尤为重要。
此外,根据 12-Factor App 的最佳实践,应用配置应通过环境变量注入,而 YAML 在 Spring 环境下的灵活结构,使其成为管理多环境配置的理想选择。
本文将深入对比 Spring 中 YAML 与 Properties 文件的差异,分析各自的优劣。不过要提醒一句:选哪个,有时候真就是“萝卜青菜,各有所爱”——但了解清楚区别,才能做出更合理的技术决策 ✅。
2. YAML 语法简介
YAML 是 “YAML Ain’t Markup Language” 的递归缩写,它具备以下优势:
- ✅ 可读性强:结构清晰,接近自然语言
- ✅ 天然支持层级结构:非常适合配置文件的树状组织
- ✅ 数据类型丰富:原生支持 map、list、标量类型等
这些特性让它成为 Spring 配置文件的绝佳选择。不过新手刚上手时可能会被它的 缩进规则 虐一下⚠️——YAML 对空格极其敏感,缩进错了,解析就崩了。
举个例子,下面这种层级结构在 YAML 中写起来非常直观:
database:
host: localhost
port: 5432
username: admin
password: secret
换成 Properties 就得写成:
database.host=localhost
database.port=5432
database.username=admin
database.password=secret
一眼就能看出谁更清爽。
3. Spring 中的 YAML 配置
正如前面所说,YAML 是一种比 Properties 更高级的配置格式。它不仅可读性好,还支持更复杂的数据结构。值得一提的是:从 1.2 版本起,YAML 已是 JSON 的超集,这意味着所有合法的 JSON 都是合法的 YAML(反过来不成立)。
在 Spring Boot 中,YAML 的另一个强大特性是:外部配置文件可以覆盖 jar 包内的默认配置。这对部署非常友好——无需重新打包,改配置即可。
此外,Spring Profiles 支持多环境隔离,而 YAML 的一个杀手级功能是:可以在一个文件中定义多个 profile,通过 ---
分隔,清爽又集中。
✅ 提示:Spring Boot 2.4.0 之前使用
spring.profiles
,之后推荐使用spring.config.activate.on-profile
以下是一个典型的多环境 YAML 配置示例:
spring:
profiles:
active:
- test
---
spring:
config:
activate:
on-profile: test
name: test-YAML
environment: testing
servers:
- www.abc.test.com
- www.xyz.test.com
---
spring:
config:
activate:
on-profile: prod
name: prod-YAML
environment: production
servers:
- www.abc.com
- www.xyz.com
---
spring:
config:
activate:
on-profile: dev
name: ${DEV_NAME:dev-YAML}
environment: development
servers:
- www.abc.dev.com
- www.xyz.dev.com
关键点解析:
spring.profiles.active
指定默认激活的 profile(这里是test
)- 可通过环境变量动态切换 profile:
export SPRING_PROFILES_ACTIVE=dev
${DEV_NAME:dev-YAML}
表示:优先取环境变量DEV_NAME
,未设置则用默认值dev-YAML
这个机制在 CI/CD 流水线中非常实用,真正做到“一套代码,多套配置”。
4. 减少重复 & 提升可读性
YAML 的层级结构天然避免了 Properties 中的“前缀重复”问题。来看个实际例子:
component:
idm:
url: myurl
user: user
password: password
description: >
this should be a long
description
service:
url: myurlservice
token: token
description: >
this should be another long
description
同样的配置,用 Properties 写就显得啰嗦:
component.idm.url=myurl
component.idm.user=user
component.idm.password=password
component.idm.description=this should be a long \
description
component.service.url=myurlservice
component.service.token=token
component.service.description=this should be another long \
description
对比总结:
特性 | YAML | Properties |
---|---|---|
✅ 层级清晰 | ✔️ | ❌ |
✅ 减少重复 | ✔️ | ❌ |
✅ 多行文本 | > 折叠换行 |
\ 续行,丑且易错 |
⚠️ 编辑体验 | 需注意缩进 | 无格式要求 |
YAML 的缩进不仅是格式要求,更是语义表达——谁属于谁,一目了然。
5. 列表与 Map 的配置
YAML 对集合类型的支持非常自然,无论是 list 还是 map,写起来都简单粗暴。
列表示例:
servers:
- www.abc.test.com
- www.xyz.test.com
external: [www.abc.test.com, www.xyz.test.com]
等价于 Properties 中的:
servers[0]=www.abc.test.com
servers[1]=www.xyz.test.com
external=www.abc.test.com, www.xyz.test.com
显然,YAML 更直观,尤其当列表变长时,Properties 的索引写法会让人抓狂。
Map 示例:
map:
firstkey: key1
secondkey: key2
Properties 中只能通过扁平化键名模拟:
map.firstkey=key1
map.secondkey=key2
虽然功能等价,但 YAML 的结构化表达在复杂配置中优势明显。
6. 测试验证
启动应用后,查看日志输出,确认配置是否生效。
默认 profile 为 test
,日志如下:
2020-06-11 13:58:28.846 INFO 10720 --- [main] com.baeldung.yaml.MyApplication: ...
using environment:testing
name:test-YAML
servers:[www.abc.test.com, www.xyz.test.com]
external:[www.abc.test.com, www.xyz.test.com]
map:{firstkey=key1, secondkey=key2}
Idm:
Url: myurl
User: user
Password: password
Description: this should be a long description
Service:
Url: myurlservice
Token: token
Description: this should be another long description
动态覆盖测试
- 设置环境变量:
export DEV_NAME=new-dev-YAML
- 切换到 dev profile:
export SPRING_PROFILES_ACTIVE=dev
输出:
2020-06-11 17:00:45.459 INFO 19636 --- [main] com.baeldung.yaml.MyApplication: ...
using environment:development
name:new-dev-YAML
servers:[www.abc.dev.com, www.xyz.dev.com]
✅ 可见 name
已被环境变量覆盖。
切换到生产环境:
export SPRING_PROFILES_ACTIVE=prod
输出:
2020-06-11 17:03:33.074 INFO 20716 --- [main] ...
using environment:production
name:prod-YAML
servers:[www.abc.com, www.xyz.com]
一切正常,profile 切换无误。
7. 总结
通过本文的对比,可以得出以下结论:
- ✅ YAML 更适合复杂、多层级的配置场景
- ✅ 减少重复、提升可读性,尤其在多 profile 环境下优势明显
- ✅ 原生支持 list、map,结构清晰,不易出错
- ⚠️ 对缩进敏感,编辑时需小心(建议用 IDE 支持)
- ❌ Properties 更适合简单配置或遗留系统迁移
最终选择哪种格式,取决于团队习惯和项目复杂度。但对于新项目,尤其是微服务或 DevOps 驱动的系统,强烈推荐使用 YAML。
💡 代码已上传至 GitHub:https://github.com/eugenp/tutorials/tree/master/spring-boot-modules/spring-boot-properties