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 对其的增强特性都是必要的技能。

相关推荐
csdn2015_1 小时前
java springboot项目,接收到的参数多个逗号
java·开发语言·spring boot
摇滚侠2 小时前
《SpringBoot 3:入门与应用实战》第 13 章 整合 MyBatis MyBatis 简单开发 阅读笔记 39
spring boot·笔记·mybatis
事圆则缓2 小时前
Java 常见数据结构与 Android 使用场景
android·java·数据结构
RisunJan2 小时前
Android 高频面试题与解答
android
MyBili2 小时前
【安卓开发/搞机】快图浏览(QuickPic)技术解析:为何这款3MB应用仍是本地图库的性能天花板?
android·app·安卓·文件管理·相册·看图软件·手机相册
Mr.敦的私房菜2 小时前
【SpringEvent】Spring Boot / Spring Framework 事件大全
spring boot·spring
程序员阿明2 小时前
spring boot4+springAI 2加redis多轮对话存储
spring boot·redis·后端
Mr.敦的私房菜2 小时前
【SpringBoot请求记录】Spring Boot Actuator 自定义记录 HTTP 服务请求
spring boot·mvc·运维开发
java1234_小锋2 小时前
MyBatis-Plus 3.5.15 已全面支持 Spring Boot 4.0 及 Jackson 3.0
java·spring boot·mybatis