YAML 的语法规则由它的设计目标决定:让人类轻松读写。它用缩进表达层级,用符号简化结构,但它对格式的细节很敏感。
以下从基础到进阶,把 YAML 的规则拆解清楚。
一、基础规则:大小写敏感 + 缩进
规则 1:大小写敏感
YAML 区分大小写。Server和server是两个不同的键。
规则 2:缩进用空格,不用 Tab
YAML 强制使用空格进行缩进。Tab 会导致解析错误。Spring Boot 的 YAML 解析器会直接报错,不会自动转换。
# 正确:用两个空格缩进server:port:8080# 错误:Tab 缩进(解析失败)server:port:8080规则 3:相同层级的元素左对齐
server:port:8080context-path:/api# 与 port 左对齐database:url:jdbc:mysql://...# 与 server 左对齐(不同父节点)规则 4::后面必须有空格
键值对中,冒号后面必须加一个空格。这是语法要求。
# 正确name:myapp# 错误(缺少空格)name:myapp二、数据结构表达
1. 对象(Map / 字典)
通过缩进表示层级。
server:port:8080timeout:30host:localhost等价于 JSON:
{"server":{"port":8080,"timeout":30,"host":"localhost"}}内联写法:
server:{port:8080,timeout:30,host:localhost}2. 数组(List / 序列)
用-加空格表示列表项。
servers:-server1-server2-server3等价于 JSON:
{"servers":["server1","server2","server3"]}内联写法:
servers:[server1,server2,server3]3. 对象列表
数组中的每个元素是一个对象。
users:-name:zhangsanage:25email:zhangsan@example.com-name:lisiage:30email:lisi@example.com等价于 JSON:
{"users":[{"name":"zhangsan","age":25,"email":"zhangsan@example.com"},{"name":"lisi","age":30,"email":"lisi@example.com"}]}4. 嵌套组合
app:name:myappversion:1.0features:cache:truelogging:falseservers:-prod-server-dev-serversecurity:enabled:trueroles:-admin-user三、纯量(Scalar)数据类型
1. 字符串
默认不加引号。包含特殊字符时用引号包裹。
# 普通字符串name:myapp# 包含空格description:This is my application# 包含特殊字符(需要引号)message:'Hello: World'# 包含冒号path:'C:\Users\admin'# 包含反斜杠quote:"He said: 'Hello'"# 包含单引号单引号 vs 双引号:
# 单引号:原样输出,不解析转义single:'Hello \n World'# 输出:Hello \n World# 双引号:解析转义字符double:"Hello \n World"# 输出:Hello(换行) World2. 多行字符串
保留换行(|):
description:|This is the first line. This is the second line. This is the third line.去掉末尾换行(>-):
description:>-This line will be folded. This is the second line.# 最终拼接为一行:This line will be folded. This is the second line.3. 数字
integer:100float:3.14negative:-50exponential:1.2e+54. 布尔值
支持多种写法:
enabled:true# 真disabled:false# 假# 也支持以下写法on:trueoff:falseyes:trueno:false5. Null
value:nullvalue:~# 等价写法6. 日期和时间
date:2024-01-01datetime:2024-01-01T10:30:00+08:00四、高级语法
1. 注释
用#添加注释。注释可以单独占一行,也可以跟在值后面。
# 服务器配置server:port:8080# 监听端口timeout:30# 超时时间(秒)2. 锚点(&)与引用(*)
复用配置片段。
defaults:&defaultstimeout:30retries:3server1:<<:*defaultshost:server1.example.comserver2:<<:*defaultshost:server2.example.comtimeout:60# 覆盖默认值解析后,server1包含timeout: 30、retries: 3、host: server1.example.com。server2的timeout被覆盖为 60。
3. 多文档块(---)
一个 YAML 文件中可以包含多个文档,用---分隔。
# 第一个文档spring:profiles:devdatasource:url:jdbc:h2:mem:dev---# 第二个文档spring:profiles:proddatasource:url:jdbc:mysql://prod:3306/dbSpring Boot 利用这个机制实现多 Profile 配置(配合spring.config.activate.on-profile)。
4. 强制类型转换
string_value:!!str100integer_value:!!int"100"boolean_value:!!bool"true"5. 空值标记
empty_list:[]# 空数组empty_map:{}# 空对象null_value:null# 空值五、Spring Boot 中的特殊规则
1.@Value注入列表
servers:-server1-server2@Value("${servers}")privateList<String>servers;// 自动拆分2.@ConfigurationProperties绑定
app:name:myapptimeout:30features:cache:truelogging:false@Component@ConfigurationProperties(prefix="app")publicclassAppProperties{privateStringname;privateinttimeout;privateMap<String,Boolean>features;}3. 配置文件加载顺序中的规则
YAML 和 properties 可以共存。同一个键在两种格式中都出现时,properties 优先级更高(先加载 YAML,后加载 properties,后者覆盖前者)。
六、常见错误
错误 1:缩进不一致
# 错误(2 空格和 4 空格混用)server:port:8080timeout:30错误 2:冒号后缺少空格
# 错误name:myapp错误 3:使用 Tab
# 错误(使用了 Tab)server:port:8080错误 4:列表项缩进不对
# 错误(列表项未左对齐)servers:-server1-server2错误 5:字符串中包含特殊字符未加引号
# 错误(冒号在字符串中)description:this is:a test# 正确(加引号)description:'this is: a test'错误 6:注释前缺少空格
# 正确port:8080# 监听端口# 错误(# 前无空格,但 YAML 仍能解析,是风格问题)port:8080# 监听端口七、总结
YAML 的关键规则:
| 规则 | 说明 |
|---|---|
| 缩进 | 只用空格,不用 Tab,相同层级左对齐 |
| 冒号 | 键值对中冒号后必须有空格 |
| 列表 | -后必须有空格 |
| 类型 | 自动推断,必要时用引号控制 |
| 注释 | #开头 |
| 多文档 | ---分隔 |
| 引用 | &定义锚点,*引用 |
YAML 的设计目标是让人类能轻松读写配置。缩进替代了 XML 的闭合标签和 JSON 的括号,这让它高度可读,也意味着任何格式错误都会导致解析失败。写配置时记住两点:缩进保持一致,冒号后面加空格,就能避免 90% 的格式问题。