Spring Boot 中使用 application.yml 与 application.properties 的区别

更新于 2025-12-30

baeldung 2020-08-22

1. 概述

在 Spring Boot 中,一种常见的做法是使用外部配置来定义属性。这使我们能够在不同环境中使用相同的代码。

我们可以使用属性文件(properties)、YAML 文件、环境变量和命令行参数进行配置。

在本简短教程中,我们将探讨 properties 文件和 YAML 文件之间的主要区别。

2. Properties 配置

默认情况下,Spring Boot 可以读取 application.properties 文件中的配置,该文件采用键值对格式:

spring.datasource.url=jdbc:h2:dev
spring.datasource.username=SA
spring.datasource.password=password

每一行代表一个独立的配置项,因此我们需要通过为键添加相同的前缀来表达层次结构数据。在上面的例子中,所有键都属于 spring.datasource 命名空间。

2.1. Properties 中的占位符

在属性值中,我们可以使用 ${} 语法引用其他键、系统属性或环境变量的内容:

app.name=MyApp
app.description=${app.name} is a Spring Boot application

2.2. 列表结构

如果存在多个具有相同类型但不同值的属性,可以使用数组索引表示列表结构:

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. 多文档 Profiles(多环境配置)

从 Spring Boot 2.4.0 版本开始,支持在单个 properties 文件中使用“多文档”格式。简单来说,我们可以将一个物理文件划分为多个逻辑文档。

这样,我们可以在同一个文件中为每个需要声明的 profile 定义独立的配置段:

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

注意:我们使用 #--- 标记来指示新文档的开始。

在此示例中,我们有两个带有不同 profile 标签的配置段。此外,还可以在根级别定义通用属性 —— 例如,logging.file.name 属性在所有 profile 中都保持一致。

2.4. 多文件 Profiles

除了将不同 profile 放在同一个文件中外,我们也可以将它们分别存储在不同的文件中。在 Spring Boot 2.4.0 之前,这是 properties 文件唯一支持的方式。

实现方法是在文件名中包含 profile 名称,例如:application-dev.ymlapplication-dev.properties

3. YAML 配置

3.1. YAML 格式

除了 Java 的 properties 文件,我们还可以在 Spring Boot 应用中使用基于 YAML 的配置文件。YAML 是一种用于指定层次化配置数据的便捷格式。

现在,让我们将前面 properties 文件中的示例转换为 YAML 格式:

spring:
  datasource:
    password: password
    url: jdbc:h2:dev
    username: SA

相比 properties 文件,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'

3.3. 多 Profile 配置

与 properties 文件不同,YAML 本身就支持多文档格式,因此无论使用哪个版本的 Spring Boot,我们都可以在同一个 YAML 文件中存储多个 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

注意:通常我们不建议在项目中同时包含标准的 application.propertiesapplication.yml 文件,因为这可能导致意外的结果。

例如,如果我们同时使用上述 YAML 文件(application.yml)和第 2.3 节中描述的 properties 配置,那么 bael.property 将被赋值为 defaultValue,而不是 profile 特定的值。这是因为 application.properties 文件加载时间晚于 application.yml,会覆盖之前设置的值。

4. Spring Boot 中的使用方式

定义好配置后,我们来看看如何在代码中访问这些配置值。

4.1. 使用 @Value 注解

我们可以使用 @Value 注解注入属性值:

@Value("${key.something}")
private String injectedProperty;

这里,属性 key.something 通过字段注入的方式注入到我们的对象中。

4.2. 使用 Environment 抽象

也可以通过 Environment API 获取属性值:

@Autowired
private Environment env;

public String getSomeKey() {
    return env.getProperty("key.something");
}

4.3. 使用 @ConfigurationProperties 注解

最后,我们还可以使用 @ConfigurationProperties 注解将属性绑定到类型安全的结构化对象中:

@ConfigurationProperties(prefix = "mail")
public class ConfigProperties {
    private String name;
    private String description;
    // ...
}

5. 结论

在本文中,我们探讨了 Spring Boot 中 properties 与 YAML 配置文件之间的一些关键区别。我们还了解了它们的值如何相互引用,并学习了如何将这些值注入到运行时环境中。