Spring Boot 中的一个常见做法是使用外部配置来定义我们的属性。这允许我们在不同的环境中使用相同的应用程序代码。
我们可以使用属性文件、YAML 文件、环境变量和命令行参数。
在这个简短的教程中,我们将探讨属性和 YAML 文件之间的主要区别。
默认情况下,Spring Boot 可以访问application.properties文件中设置的配置,该文件使用键值格式:
spring.datasource.url=jdbc:h2:dev
spring.datasource.username=SA
spring.datasource.password=password
这里每一行都是一个单独的配置,所以我们需要通过为我们的键使用相同的前缀来表达分层数据。在这个例子中,每个键都属于spring.datasource。
在我们的值中,我们可以使用带有${}语法的占位符来引用其他键、系统属性或环境变量的内容:
app.name=MyApp
app.description=${app.name} is a Spring Boot application
如果我们有不同值的同一种属性,我们可以用数组索引来表示列表结构:
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.4.0 版本开始,Spring Boot 支持创建多文档属性文件。简单地说,我们可以将单个物理文件拆分为多个逻辑文档。
这允许我们为需要声明的每个配置文件定义一个文档,所有这些都在同一个文件中:
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
请注意,我们使用 '#---' 符号来指示我们要在哪里拆分文档。
在此示例中,我们有两个带有不同轮廓标记的弹簧部分。此外,我们可以在根级别拥有一组通用属性——在这种情况下,所有配置文件中的logging.file.name属性都是相同的。
作为在同一个文件中拥有不同配置文件的替代方法,我们可以在不同文件中存储多个配置文件。在 2.4.0 版之前,这是唯一可用于属性文件的方法。
我们通过将配置文件的名称放在文件名中来实现这一点——例如,application-dev.yml或 application-dev.properties。
除了 Java 属性文件,我们还可以在 Spring Boot 应用程序中使用基于YAML的配置文件。YAML 是一种用于指定分层配置数据的便捷格式。
现在让我们从属性文件中获取相同的示例并将其转换为 YAML:
spring:
datasource:
password: password
url: jdbc:h2:dev
username: SA
这比它的属性文件替代品更具可读性,因为它不包含重复的前缀。
YAML 有更简洁的格式来表达列表:
application:
servers:
- ip: '127.0.0.1'
path: '/path1'
- ip: '127.0.0.2'
path: '/path2'
- ip: '127.0.0.3'
path: '/path3'
与属性文件不同,YAML 在设计上支持多文档文件,这样,无论我们使用哪个版本的 Spring Boot,我们都可以将多个配置文件存储在同一个文件中。
然而,在这种情况下,规范表明我们必须使用三个破折号来表示新文档的开始:
logging:
file:
name: myapplication.log
---
spring:
config:
activate:
on-profile: staging
datasource:
password: 'password'
url: jdbc:h2:staging
username: SA
bael:
property: stagingValue
注意:我们通常不希望在我们的项目中同时包含标准的application.properties和application.yml 文件,因为这可能会导致意想不到的结果。
例如,如果我们将上面显示的属性(在application.yml文件中)与第 2.3 节中描述的属性结合起来,那么bael.property将被分配 defaultValue 而不是配置文件特定的值。这仅仅是因为application.properties 稍后加载,覆盖了分配到该点的值。
现在我们已经定义了我们的配置,让我们看看如何访问它们。
我们可以使用@Value注解注入我们的属性值:
@Value("${key.something}")
private String injectedProperty;
这里属性key.something通过字段注入注入到我们的一个对象中。
我们还可以使用Environment API 获取属性的值:
@Autowired
private Environment env;
public String getSomeKey(){
return env.getProperty("key.something");
}
最后,我们还可以使用@ConfigurationProperties 注解将我们的属性绑定到类型安全的结构化对象:
@ConfigurationProperties(prefix = "mail")
public class ConfigProperties {
String name;
String description;
...
在本文中,我们看到了 属性和yml Spring Boot 配置文件之间的一些差异。我们还看到了它们的值如何引用其他属性。最后,我们研究了如何将值注入到我们的运行时中。
与往常一样,所有代码示例都可以在 GitHub 上找到。