文章目录
- 一、YAML基础:不仅仅是语法
-
- [1.1 YAML文件特性](#1.1 YAML文件特性)
- [1.2 properties vs YAML:直观对比](#1.2 properties vs YAML:直观对比)
- 二、YAML配置语法详解
-
- [2.1 配置简单数据](#2.1 配置简单数据)
- [2.2 配置对象数据](#2.2 配置对象数据)
- [2.3 配置集合数据](#2.3 配置集合数据)
- [三、Spring Boot读取YAML配置](#三、Spring Boot读取YAML配置)
-
- [3.1 使用@Value注解(适合简单配置)](#3.1 使用@Value注解(适合简单配置))
-
- [3.2 使用@ConfigurationProperties(推荐用于复杂配置)](#3.2 使用@ConfigurationProperties(推荐用于复杂配置))
- 四、YAML高级特性
-
- [4.1 使用占位符](#4.1 使用占位符)
- [4.2 Spring Boot提供的随机数生成器](#4.2 Spring Boot提供的随机数生成器)
- 五、配置文件位置与优先级
-
- [5.1 配置文件存放位置](#5.1 配置文件存放位置)
- [5.2 优先级规则](#5.2 优先级规则)
- [5.3 多环境配置策略](#5.3 多环境配置策略)
- 六、高级主题:bootstrap配置文件
-
- [6.1 什么是bootstrap配置?](#6.1 什么是bootstrap配置?)
- [6.2 使用场景示例](#6.2 使用场景示例)
- 七、实战技巧与最佳实践
-
- [7.1 配置验证](#7.1 配置验证)
- [7.2 配置分组与文档化](#7.2 配置分组与文档化)
- [7.3 敏感信息处理](#7.3 敏感信息处理)
- 八、常见问题与解决方案
- 总结
前言
在Spring Boot项目中,配置管理是应用开发的重要环节。虽然Spring
Boot为大多数配置提供了合理的默认值,但在实际项目中,我们经常需要根据需求进行个性化配置。传统上,我们使用
application.properties文件进行配置,但近年来,YAML格式因其出色的可读性和结构化特性,已经成为SpringBoot配置的首选格式个人主页:艺杯羹
系列专栏:SpringBoot3
一、YAML基础:不仅仅是语法
1.1 YAML文件特性
YAML(YAML Ain't Markup Language)是一种人类友好的数据序列化标准,特别适合用于配置文件。Spring Boot默认支持YAML格式,文件扩展名可以是.yml或.yaml。
核心特性:
- 大小写敏感 :
server和Server被视为不同的配置 - 缩进代表层级:使用空格(通常2个或4个)表示层级关系
- 冒号后必须有空格 :
key: value是正确的,key:value是错误的

1.2 properties vs YAML:直观对比
properties格式:
properties
server.port=8888
server.servlet.context-path=/itbaizhan
database.url=jdbc:mysql://localhost:3306/test
database.username=root
database.password=123456
YAML格式:
yaml
server:
port: 8888
servlet:
context-path: /itbaizhan
database:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
YAML的层次结构让相关配置自然分组,大大提升了可读性。
二、YAML配置语法详解
2.1 配置简单数据
yaml
# 简单键值对
app:
name: "SpringBoot学习"
version: "1.0.0"
production-mode: false
2.2 配置对象数据
方式一:缩进表示法(推荐)
yaml
database:
primary:
url: jdbc:mysql://localhost:3306/primary
username: admin
password: admin123
pool-size: 10
secondary:
url: jdbc:mysql://localhost:3306/secondary
username: readonly
password: read123
pool-size: 5
方式二:行内表示法
yaml
user: {name: "张三", age: 25, email: "zhangsan@example.com"}
2.3 配置集合数据
列表表示法:
yaml
# 字符串列表
white-list:
- 192.168.1.1
- 192.168.1.2
- 192.168.1.100
# 数字列表
ports:
- 8080
- 8081
- 9000
# 对象列表
users:
- id: 1
name: "张三"
role: "ADMIN"
- id: 2
name: "李四"
role: "USER"
- id: 3
name: "王五"
role: "USER"
行内列表表示法:
yaml
cities: [北京, 上海, 广州, 深圳]
三、Spring Boot读取YAML配置
3.1 使用@Value注解(适合简单配置)
@Value注解适用于读取简单的配置值,语法为@Value("${配置路径}")。

示例配置:
yaml
app:
name: "学习平台"
email:
system: system@itbaizhan.com
support: support@itbaizhan.com
upload:
max-size: 10MB
allowed-types:
- image/jpeg
- image/png
- application/pdf
读取配置的Controller:
java
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConfigController {
// 读取简单值
@Value("${app.name}")
private String appName;
// 读取嵌套属性
@Value("${email.system}")
private String systemEmail;
// 读取列表中的元素
@Value("${upload.allowed-types[0]}")
private String firstAllowedType;
// 读取并转换类型
@Value("${upload.max-size}")
private String maxUploadSize;
@GetMapping("/config")
public String showConfig() {
return String.format("应用名称: %s<br>系统邮箱: %s<br>首允许类型: %s<br>最大上传: %s",
appName, systemEmail, firstAllowedType, maxUploadSize);
}
@GetMapping("/app-info")
public AppInfo getAppInfo() {
return new AppInfo(appName, systemEmail);
}
// 静态内部类,用于返回结构化数据
static class AppInfo {
private String name;
private String email;
// 构造函数、getters和setters
public AppInfo(String name, String email) {
this.name = name;
this.email = email;
}
// 省略getters和setters
}
}
局限性:
- 只能映射简单类型(String、int、boolean等)
- 无法直接映射对象或复杂集合
- 每个字段都需要单独注解
3.2 使用@ConfigurationProperties(推荐用于复杂配置)
对于复杂的配置结构,@ConfigurationProperties是更好的选择,它可以将配置自动绑定到Java Bean。
步骤1:创建配置类
java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Component
@ConfigurationProperties(prefix = "app.config")
public class AppProperties {
private String name;
private String version;
private Database database;
private Security security;
private List<String> features;
private Map<String, String> metadata;
// 嵌套配置类
public static class Database {
private String url;
private String username;
private String password;
private int connectionTimeout;
private int maxPoolSize;
// getters和setters
public String getUrl() { return url; }
public void setUrl(String url) { this.url = url; }
// 其他getters和setters...
}
public static class Security {
private boolean enabled;
private String secretKey;
private int tokenExpiration;
private List<String> allowedOrigins;
// getters和setters
public boolean isEnabled() { return enabled; }
public void setEnabled(boolean enabled) { this.enabled = enabled; }
// 其他getters和setters...
}
// 主类的getters和setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
// 其他getters和setters...
}
步骤2:YAML配置
yaml
app:
config:
name: "企业级应用"
version: "2.1.0"
database:
url: "jdbc:mysql://localhost:3306/enterprise"
username: "admin"
password: "securePass123!"
connection-timeout: 30000
max-pool-size: 20
security:
enabled: true
secret-key: "mySuperSecretKey123"
token-expiration: 3600
allowed-origins:
- "https://example.com"
- "https://api.example.com"
features:
- "用户管理"
- "权限控制"
- "数据导出"
- "报表生成"
metadata:
environment: "production"
region: "us-east-1"
deploy-time: "2024-01-15T10:30:00Z"
步骤3:使用配置类
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AppInfoController {
@Autowired
private AppProperties appProperties;
@GetMapping("/app-properties")
public String getAppProperties() {
StringBuilder sb = new StringBuilder();
sb.append("应用名称: ").append(appProperties.getName()).append("<br>");
sb.append("版本: ").append(appProperties.getVersion()).append("<br>");
sb.append("数据库URL: ").append(appProperties.getDatabase().getUrl()).append("<br>");
sb.append("安全启用: ").append(appProperties.getSecurity().isEnabled()).append("<br>");
sb.append("功能列表: ").append(String.join(", ", appProperties.getFeatures()));
return sb.toString();
}
@GetMapping("/database-info")
public AppProperties.Database getDatabaseInfo() {
return appProperties.getDatabase();
}
}
优势:
- 类型安全:自动类型转换
- 验证支持:可与JSR-303验证注解结合使用
- IDE支持:良好的代码提示
- 结构化:保持配置的逻辑分组
四、YAML高级特性
4.1 使用占位符
占位符让配置更加灵活和DRY(Don't Repeat Yourself)。
基本用法:
yaml
server:
port: 8080
app:
# 引用其他配置值
base-url: "http://localhost:${server.port}"
# 组合多个值
api-url: "${app.base-url}/api/v1"
logging:
# 使用系统属性
file: "logs/${app.name:-defaultApp}.log"
与随机值结合:
yaml
# 开发环境配置示例
dev:
# 随机端口,避免冲突
server:
port: ${random.int(8000,8999)}
database:
# 随机生成测试数据
test-data:
user-count: ${random.int(100,1000)}
transaction-id: ${random.uuid}
# 组合使用
connection-string: "jdbc:mysql://localhost:${dev.server.port}/test_${random.value}"
4.2 Spring Boot提供的随机数生成器
Spring Boot内置了方便的随机数生成方法:
yaml
app:
# 各种随机值示例
secrets:
# 类似UUID但无连字符
token: ${random.value}
# 标准UUID
session-id: ${random.uuid}
# 随机整数
default-code: ${random.int}
# 10以内的随机数
retry-count: ${random.int(10)}
# 范围随机数
timeout-ms: ${random.int(1000,5000)}
# 随机长整型
big-id: ${random.long}
# 范围长整型
transaction-id: ${random.long(1000000,9999999)}
五、配置文件位置与优先级
5.1 配置文件存放位置
Spring Boot会从以下位置按顺序查找配置文件:
- 项目根目录下的/config子目录
- 项目根目录
- classpath下的/config目录(即resources/config)
- classpath根目录(即resources)
5.2 优先级规则
优先级从高到低:
1. 项目根目录/config/application.yml
2. 项目根目录/application.yml
3. classpath:/config/application.yml
4. classpath:/application.yml
实际应用场景:
bash
# 项目结构示例
my-springboot-app/
├── config/ # 最高优先级
│ └── application.yml # 生产环境配置(可覆盖默认值)
├── src/
│ └── main/
│ └── resources/
│ ├── config/ # 中等优先级
│ │ └── application-dev.yml # 开发环境配置
│ └── application.yml # 最低优先级,基础配置
└── application.yml # 次高优先级,本地覆盖配置
5.3 多环境配置策略
通过激活不同profile实现环境隔离:
yaml
# application.yml(基础配置)
spring:
profiles:
active: @activatedProperties@ # Maven/Gradle属性替换
app:
name: "多环境应用"
version: "1.0.0"
---
# 开发环境配置
spring:
config:
activate:
on-profile: "dev"
server:
port: 8080
database:
url: "jdbc:h2:mem:testdb"
show-sql: true
logging:
level:
root: DEBUG
---
# 测试环境配置
spring:
config:
activate:
on-profile: "test"
server:
port: 8081
database:
url: "jdbc:mysql://test-db:3306/app_test"
username: "tester"
password: "test123"
logging:
level:
root: INFO
---
# 生产环境配置
spring:
config:
activate:
on-profile: "prod"
server:
port: 80
ssl:
enabled: true
database:
url: "jdbc:mysql://prod-db:3306/app_prod"
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
logging:
file:
name: "/var/log/app/app.log"
level:
root: WARN
六、高级主题:bootstrap配置文件
6.1 什么是bootstrap配置?
在Spring Cloud微服务架构中,bootstrap配置文件扮演着特殊角色:
- 加载时机更早:在application context之前加载
- 不可覆盖性:配置具有最高优先级
- 特殊用途:主要用于外部配置中心连接
6.2 使用场景示例
bootstrap.yml:
yaml
# 连接到配置中心
spring:
cloud:
config:
uri: http://config-server:8888
name: my-application
profile: ${SPRING_PROFILES_ACTIVE:dev}
label: main
# 加密配置(优先加载)
encrypt:
key: ${ENCRYPT_KEY:defaultEncryptKey}
# 应用基础元数据(不可覆盖)
app:
id: my-application-001
cluster: production-cluster
application.yml:
yaml
# 常规应用配置
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: user
password: pass
# 其他业务配置...
七、实战技巧与最佳实践
7.1 配置验证
结合JSR-303验证确保配置正确性:
java
import javax.validation.constraints.*;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
@Component
@Validated
@ConfigurationProperties(prefix = "app.validated")
public class ValidatedProperties {
@NotBlank(message = "应用名称不能为空")
private String name;
@Min(value = 1, message = "版本号必须大于0")
private int version;
@Email(message = "管理员邮箱格式不正确")
private String adminEmail;
@Pattern(regexp = "^https?://.*", message = "URL必须以http或https开头")
private String baseUrl;
@Size(min = 1, max = 10, message = "功能列表至少1个,最多10个")
private List<String> features;
// getters和setters...
}
7.2 配置分组与文档化
yaml
# ============================================
# 应用基础配置
# ============================================
app:
info:
name: "企业管理系统"
version: "2.1.0"
description: "用于企业内部管理的核心系统"
# ============================================
# 服务器配置
# ============================================
server:
port: 8080
servlet:
context-path: /ems
session:
timeout: 30m
# ============================================
# 数据库配置
# ============================================
spring:
datasource:
primary:
url: jdbc:mysql://localhost:3306/primary_db
username: ${DB_USER:root}
password: ${DB_PASSWORD:}
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: 20
minimum-idle: 5
connection-timeout: 30000
# ============================================
# 缓存配置
# ============================================
cache:
redis:
host: localhost
port: 6379
timeout: 5000
# 缓存键前缀,避免冲突
key-prefix: "ems:"
# ============================================
# 业务配置
# ============================================
business:
user:
default-password: "ChangeMe123"
password-expire-days: 90
max-login-attempts: 5
file:
upload:
max-size: 50MB
allowed-extensions: [".pdf", ".doc", ".docx", ".xls", ".xlsx"]
storage-path: "/var/uploads"
7.3 敏感信息处理
避免硬编码密码:
yaml
# 使用环境变量
database:
password: ${DATABASE_PASSWORD}
# 使用JVM参数(启动时传入)
api:
key: ${API_KEY:defaultKeyIfNotSet}
# 外部配置文件(git忽略此文件)
secrets:
# 从外部文件导入,该文件不在版本控制中
@include: file:/opt/app/secrets.yml
八、常见问题与解决方案
问题1:YAML语法错误
症状 :应用启动失败,提示YAML解析错误
解决:使用在线YAML验证工具检查语法,特别注意缩进和冒号后的空格
问题2:配置未生效
症状 :修改配置后应用行为未改变
解决:
- 检查配置文件位置和优先级
- 确认是否使用了正确的profile
- 查看Spring Boot启动日志中的"Active Profiles"
问题3:复杂对象绑定失败
症状 :@ConfigurationProperties无法绑定嵌套对象
解决:
- 确保有默认构造函数
- 提供完整的getter和setter
- 使用
@Validated和@Valid注解进行嵌套验证
总结
YAML与Properties语法对比表
| 特性 | Properties格式 | YAML格式 | 优势 |
|---|---|---|---|
| 语法 | 键值对,使用=连接 |
键值对,使用:连接(后跟空格) |
YAML更接近自然语言 |
| 层级表示 | 使用.表示层级 |
使用缩进表示层级 | YAML层级关系更直观 |
| 数据格式 | 简单字符串,需自行解析复杂类型 | 原生支持对象、列表等复杂类型 | YAML数据结构更丰富 |
| 可读性 | 一般,配置复杂时难以阅读 | 优秀,结构清晰易读 | YAML适合复杂配置 |
| 注释 | 使用# |
使用# |
相同 |
| 多行文本 | 不支持原生多行,需转义 | 支持多行文本(使用` | 或>`) |
| 示例 | server.port=8080 |
server: port: 8080 |
YAML更结构化 |
希望这篇教程能帮助你在Spring Boot配置管理的道路上更进一步。实践是最好的学习方式,现在就去创建你的第一个YAML配置文件吧!