1. 概述
在 Spring Boot 项目中,外部化配置是标配操作✅。通过配置文件,我们可以让同一套代码在不同环境(如 dev、prod)中运行,而无需修改代码。
Spring Boot 支持多种配置方式:properties 文件、YAML 文件、环境变量、命令行参数等。
本文重点对比两种最常见的配置文件格式:application.properties
和 application.yml
,帮你避开一些常见踩坑⚠️,并选出最适合你项目的方案。
2. Properties 配置
默认情况下,Spring Boot 会加载 application.properties
文件,它采用简单的 key-value 形式:
spring.datasource.url=jdbc:h2:dev
spring.datasource.username=SA
spring.datasource.password=password
✅ 优点:结构简单,兼容性好,IDE 支持完善。
❌ 缺点:层级深时,重复前缀多,可读性差。
2.1. 占位符(Placeholders)
可以在值中使用 ${}
引用其他配置项、系统属性或环境变量,非常实用:
app.name=MyApp
app.description=${app.name} is a Spring Boot application
这样 app.description
的值最终是 "MyApp is a Spring Boot application"
。
2.2. 列表结构
Properties 本身不支持数组,但可以通过索引模拟列表:
application.servers[0].ip=127.0.0.1
application.servers[0].path=/path1
application.servers[1].ip=127.0.0.2
application.servers[1].path=/path2
application.servers[2].ip=127.0.0.3
application.servers[2].path=/path3
这种方式虽然能用,但写起来啰嗦,维护成本高。
2.3. 多 Profile 支持(单文件多文档)
从 Spring Boot 2.4.0 开始,支持在 单个 properties 文件中定义多个逻辑文档,用 #---
分隔:
logging.file.name=myapplication.log
bael.property=defaultValue
#---
spring.config.activate.on-profile=dev
spring.datasource.password=password
spring.datasource.url=jdbc:h2:dev
spring.datasource.username=SA
bael.property=devValue
#---
spring.config.activate.on-profile=prod
spring.datasource.password=password
spring.datasource.url=jdbc:h2:prod
spring.datasource.username=prodUser
bael.property=prodValue
✅ 这样可以把所有环境的配置集中在一个文件里,适合配置项不多的场景。
⚠️ 注意:#---
前后不能有空格,否则解析失败。
2.4. 多 Profile 支持(多文件方式)
另一种经典做法是按 profile 拆分文件,比如:
application-dev.properties
application-prod.properties
application-staging.properties
这是 2.4.0 之前的唯一方式,至今仍被广泛使用,结构清晰,适合大型项目。
3. YAML 配置
3.1. YAML 格式优势
YAML 是一种更适合表达 层级结构 的格式,Spring Boot 原生支持。相比 properties,它更简洁、可读性更强。
将前面的 properties 配置转为 YAML:
spring:
datasource:
password: password
url: jdbc:h2:dev
username: SA
✅ 没有重复前缀,结构一目了然。
⚠️ 注意缩进!YAML 对空格敏感,缩进错误会导致解析失败。
3.2. 列表结构(更简洁)
YAML 原生支持列表,写起来简单粗暴:
application:
servers:
- ip: '127.0.0.1'
path: '/path1'
- ip: '127.0.0.2'
path: '/path2'
- ip: '127.0.0.3'
path: '/path3'
相比 properties 的 [0]
、[1]
,YAML 的 -
语法更直观,维护更方便。
3.3. 多 Profile 支持(天然支持)
YAML 原生支持多文档,使用 ---
分隔(注意是三个短横线):
logging:
file:
name: myapplication.log
---
spring:
config:
activate:
on-profile: staging
datasource:
password: 'password'
url: jdbc:h2:staging
username: SA
bael:
property: stagingValue
✅ 无论 Spring Boot 版本如何,YAML 都支持这种写法。
⚠️ 踩坑提醒:**不要同时存在 application.properties
和 application.yml
**!
Spring Boot 加载顺序是:application.properties
会 覆盖 application.yml
中的同名配置。
例如,如果你在 yml
中为 bael.property
设了 profile 值,但 properties
文件里也有同名 key,最终会以 properties
为准,导致 profile 配置失效。
4. 如何在代码中使用配置
定义好配置后,怎么读取?常见三种方式:
4.1. 使用 @Value 注解
最简单直接的方式,适合零星配置:
@Value("${key.something}")
private String injectedProperty;
⚠️ 注意:不支持复杂结构(如 List、嵌套对象),且不利于重构(改 key 名时 IDE 不会自动提示)。
4.2. 使用 Environment 接口
更灵活,适合动态获取配置:
@Autowired
private Environment env;
public String getSomeKey(){
return env.getProperty("key.something");
}
✅ 可以设置默认值:env.getProperty("key.something", "defaultValue")
✅ 适合在代码中动态判断配置是否存在。
4.3. 使用 @ConfigurationProperties
推荐方式✅,适合结构化配置。将配置绑定到类型安全的 POJO:
@ConfigurationProperties(prefix = "mail")
public class ConfigProperties {
private String name;
private String description;
// getter & setter
}
然后在配置类上加上 @EnableConfigurationProperties(ConfigProperties.class)
或直接使用 @Component
。
✅ 类型安全,IDE 友好,支持嵌套对象、列表、校验(配合 @Validated
)。
✅ 配置集中管理,易于维护。
5. 总结
特性 | properties | YAML |
---|---|---|
可读性 | 一般,层级深时差 | ✅ 优秀,适合复杂结构 |
列表支持 | ❌ 索引模拟,啰嗦 | ✅ 原生支持,简洁 |
多 Profile | ✅ 2.4+ 支持单文件多文档 | ✅ 原生支持 |
IDE 支持 | ✅ 完善 | ✅ 大部分支持,注意缩进警告 |
安全隐患 | ❌ 明文写密码,风险高 | ❌ 同样问题,建议配合加密工具 |
✅ 推荐实践:
- 小项目 or 团队习惯 properties → 用
application.properties
- 中大型项目 or 配置复杂 → 用
application.yml
- 绝对不要同时存在
.properties
和.yml
文件 - 优先使用
@ConfigurationProperties
,告别魔法字符串
所有示例代码已上传至 GitHub:https://github.com/baeldung/spring-boot-tutorials