Spring Boot 中的 YAML 完全指南

Spring Boot 中的 YAML 完全指南

一、YAML 是什么?

YAML 是一种人类可读的数据序列化格式,全称是 "YAML Ain't Markup Language"。它比 properties 和 XML 更适合作为配置文件,因为它使用缩进表示层级关系,结构更清晰,表达力更强,而且支持更丰富的数据类型。

Spring Boot 默认支持 YAML 格式的配置文件,文件名通常是 application.yml。它的设计理念是让配置文件既容易阅读也容易编写,尤其适合现代微服务应用中复杂的配置场景。

二、YAML 基础语法

YAML 的基本结构是 key-value 对,用 : 分隔键和值。冒号后面必须有一个空格,这是 YAML 的硬性语法要求。

2.1 键值对

yaml 复制代码
name: myapp
port: 8080
enabled: true

这对应 properties 写法:

properties 复制代码
name=myapp
port=8080
enabled=true

2.2 层级结构

YAML 使用缩进表示层级关系,缩进必须使用空格(不能使用 Tab),建议统一使用 2 个空格。相同层级的元素必须左对齐。

yaml 复制代码
server:
  port: 8080
  context-path: /api
  tomcat:
    max-threads: 200
    uri-encoding: UTF-8

对应 properties:

properties 复制代码
server.port=8080
server.context-path=/api
server.tomcat.max-threads=200
server.tomcat.uri-encoding=UTF-8

2.3 注释

使用 # 表示注释:

yaml 复制代码
# 服务器配置
server:
  port: 8080  # 启动端口

2.4 字符串值

字符串通常不需要加引号,但如果包含特殊字符(如 :、#、%、\n、{、}等),需要用单引号或双引号包裹。

yaml 复制代码
# 普通字符串
name: myapp
description: This is my application

# 需要引号的字符串
message: 'Hello: World'     # 包含冒号
path: 'C:\Users\admin'      # 包含反斜杠

单引号和双引号的区别:

  • 单引号:原样输出,不转义特殊字符
  • 双引号:支持转义,可以使用 \n、\t 等
yaml 复制代码
single: 'Hello \n World'    # 输出:Hello \n World
double: "Hello \n World"    # 输出:Hello (换行) World

2.5 配置重复项

在 YAML 中,重复的键会导致后面的值覆盖前面的值。Spring Boot 不会报错,但会有日志警告。因此编写配置时要保证键的唯一性。

三、YAML 支持的数据类型

3.1 基本类型

yaml 复制代码
string-value: Hello
integer-value: 100
float-value: 3.14
boolean-value: true
null-value: null  # 或 ~

3.2 列表/数组

方式一:- 列表项

yaml 复制代码
servers:
  - server1.example.com
  - server2.example.com
  - server3.example.com

方式二:内联写法

yaml 复制代码
servers: [server1.example.com, server2.example.com, server3.example.com]

对应 Java:

java 复制代码
@Value("${servers}")
private List<String> servers;

3.3 Map / 对象

yaml 复制代码
features:
  cache: true
  logging: false
  audit: true

对应 Java:

java 复制代码
@Value("#{${features}}")
private Map<String, Boolean> features;

或者使用 @ConfigurationProperties:

java 复制代码
@Component
@ConfigurationProperties(prefix = "features")
public class FeaturesProperties {
    private boolean cache;
    private boolean logging;
    private boolean audit;
}

3.4 对象列表

yaml 复制代码
users:
  - name: zhangsan
    age: 25
    email: zhangsan@example.com
  - name: lisi
    age: 30
    email: lisi@example.com

对应 Java:

java 复制代码
@Component
@ConfigurationProperties(prefix = "users")
public class UserProperties {
    private List<User> users;
    
    @Data
    public static class User {
        private String name;
        private int age;
        private String email;
    }
}

3.5 复杂嵌套

yaml 复制代码
database:
  primary:
    url: jdbc:mysql://localhost:3306/main
    username: root
    password: 123456
    pool:
      max-active: 20
      min-idle: 5
  secondary:
    url: jdbc:mysql://localhost:3306/backup
    username: backup
    password: 654321
    pool:
      max-active: 10
      min-idle: 2

四、Spring Boot 对 YAML 的增强

4.1 多文档块(Profile 支持)

YAML 支持在一个文件中使用 --- 分隔多个文档块,每个文档块可以定义不同的 Profile 配置。

yaml 复制代码
# 默认配置(第一个文档块)
server:
  port: 8080

---
# 开发环境配置
spring:
  config:
    activate:
      on-profile: dev
server:
  port: 8080
logging:
  level:
    root: DEBUG

---
# 生产环境配置
spring:
  config:
    activate:
      on-profile: prod
server:
  port: 80
logging:
  level:
    root: WARN

上面的配置定义了三个文档块:默认配置、开发环境配置(Profile dev 生效)、生产环境配置(Profile prod 生效)。当激活 dev Profile 时,默认配置中的 server.port 会被 dev 块覆盖。

4.2 占位符引用

yaml 复制代码
app:
  name: myapp
  version: 1.0
  description: ${app.name} - ${app.version}

4.3 属性引用

yaml 复制代码
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: ${spring.datasource.username}_123  # 引用自身

4.4 默认值和随机值

yaml 复制代码
app:
  timeout: ${TIMEOUT:30}
  secret: ${random.value}
  uuid: ${random.uuid}

五、YAML 与 properties 对比

维度 YAML properties
可读性 树形结构,清晰易读 扁平结构,重复前缀多
层级表达 通过缩进 通过 . 分隔
列表支持 原生支持(- 列表项) 使用 [0] 索引或逗号分隔
Map 支持 原生支持(缩进层级) 支持,但层级深时难以阅读
多文档支持 支持 --- 分隔 需要多个文件
注释支持 # #
字符串转义 支持 \n、\t 等 不支持
类型推断 根据值自动推断类型 全部是字符串
与 Spring Boot 兼容性 完全兼容 完全兼容
适用场景 复杂层级配置 简单配置

六、常见问题与避坑指南

6.1 缩进问题

YAML 对缩进非常敏感,缩进不正确会导致配置解析失败或行为异常。

yaml 复制代码
# 错误:缩进不一致
server:
    port: 8080        # 4 个空格
  context-path: /api  # 2 个空格,层级错乱

# 正确:相同层级对齐
server:
  port: 8080
  context-path: /api

6.2 Tab 与空格

YAML 不允许使用 Tab 缩进,必须使用空格。IDEA 默认将 Tab 转换为空格,通常不会出问题。如果从其他地方复制配置,需要检查缩进字符。

6.3 列表与 Map 的解析陷阱

yaml 复制代码
features:
  cache: true
  logging: false

如果使用 @Value 注入 Map,必须使用 SpEL:

java 复制代码
@Value("#{${features}}")
private Map<String, Boolean> features;

如果使用 @ConfigurationProperties,可以直接绑定。

6.4 配置覆盖行为

在 Spring Boot 中,多个 application-{profile}.yml 文件共存时,后加载的 profile 配置会覆盖前面的。同一个文件中的重复键也会被覆盖(后面的覆盖前面的)。

6.5 对象列表的索引陷阱

使用 properties 格式定义对象列表时,必须用数字索引。而 YAML 中可以用 - 列表项,更直观。

properties 复制代码
users[0].name=zhangsan
users[0].age=25
users[1].name=lisi
users[1].age=30

七、最佳实践

  • 优先使用 YAML 格式,在配置项较多时优势明显
  • 保持缩进一致(2 个空格)
  • 使用 @ConfigurationProperties 绑定复杂配置,而不是用 @Value 分散注入
  • 合理使用 Profile 管理多环境配置,避免在配置文件中硬编码环境信息
  • 不要在生产配置中使用 ${random.value},这会破坏幂等性
  • 敏感信息使用环境变量占位符,避免硬编码在 YAML 中
  • 为自定义配置添加 spring-boot-configuration-processor,获得 IDEA 自动补全提示

八、总结

YAML 是 Spring Boot 推荐的配置文件格式,它让配置表达更清晰、更接近人的阅读习惯。缩进表示层级是多层配置的天然表达方式,列表和对象结构比 properties 更容易书写和维护。与 properties 相比,YAML 让配置文件从"扁平键值对"变为"结构化文档",更适合管理大型应用中的复杂配置。当配置层级超过两层或包含列表结构时,YAML 的价值会明显体现出来。无论是小规模应用还是大规模微服务项目,掌握 YAML 的语法和 Spring Boot 对其的增强特性都是必要的技能。

相关推荐
千里马学框架3 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
vipxieliang3 天前
ValidX 在 DDD 领域驱动设计中的实践
java·spring boot
致远ccc3 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
kybs19913 天前
全球灾害数据分析可视化 毕业设计-附源码66794
vue.js·spring boot·mysql·安全·django·c#·asp.net
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
码兄科技3 天前
24小时自助健身房系统软件开发实战指南:功能设计与部署方案
java·spring boot·uni-app