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

动态覆盖测试

  1. 设置环境变量:
export DEV_NAME=new-dev-YAML
  1. 切换到 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


原始标题:Spring YAML vs Properties | Baeldung