1. 概述

在 Spring Boot 项目中,外部化配置是标配操作✅。通过配置文件,我们可以让同一套代码在不同环境(如 dev、prod)中运行,而无需修改代码。

Spring Boot 支持多种配置方式:properties 文件、YAML 文件、环境变量、命令行参数等。

本文重点对比两种最常见的配置文件格式:application.propertiesapplication.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.propertiesapplication.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


原始标题:Using application.yml vs application.properties in Spring Boot | Baeldung