Spring Boot 中的 application.yml 和 application.properties

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

如上,每一行都是一个单独的配置,因此需要为 key 使用相同的前缀来表达分层数据。在本例中,每个 key 都属于 spring.datasource

2.1、Properties 中的占位符

在值中,可以使用 ${} 语法的占位符来引用其他 key、系统属性或环境变量的内容:

app.name=MyApp
app.description=${app.name} 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、多文档

自 2.4.0 版起,Spring Boot 支持创建多文档 properties 文件。简单地说,可以将单个物理文件拆分成多个逻辑文档。

这样,就可以在同一个 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

使用 #--- 符号来表示要分割文档的位置。

在本例中,定义了 2 个 Profile (devprod)。此外,还在根级别设置了一组通用属性 - 在这种情况下,所有 Profile 中的 logging.file.name 属性都相同。

2.4、多文件 Profile

除了在同一个文件中存储不同的 Profile 外,可以将多个 Profile 存储在不同的文件中。

这需要在文件名中加入 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 文件更易阅读。

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、多文档

与 properties 文件不同,YAML 在设计上支持多文档文件,这样,无论使用哪个版本的 Spring Boot,都可以在同一个文件中存储多个 Profile。

使用三个破折号(---)来表示新文档的开始:

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 文件,因为这容易出现意外。

例如,如果将上述属性(在 application.yml 文件中)与第 2.3 节中描述的 properties 同时使用,那么 bael.property 将被设置为 defaultValue,而不是特定 Profile 的值。这是因为 application.properties 文件后加载,覆盖了前面分配的值。

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 {
    String name;
    String description;
...

5、总结

本文介绍了 Spring Boot 中 properties 和 yml 配置文件之间的一些区别,以及 Spring Boot 在运行时读取配置文件中属性值的几种方式。


Ref:https://www.baeldung.com/spring-boot-yaml-vs-properties