在 Spring Boot 中把 YAML 属性绑定到 Map
1、概览
本文将带你了解如何在 Spring Boot 中把 YAML 属性注入到 Map
。
2、Spring 中的 YAML 文件
使用 YAML 文件存储外部配置数据是 Spring 开发人员的常见做法。Spring 支持使用 YAML 作为 Properties 的替代。
Spring 底层使用 SnakeYAML 来解析 YAML。
话不多说,来看看典型的 YAML 文件是什么样的:
server:
port: 8090
application:
name: myapplication
url: http://myapplication.com
如你所见,YAML 文件不言自明,而且更易于人阅读。YAML 提供了一种精美而简洁的方式来存储层次化的配置数据。
默认情况下,Spring Boot 会在应用启动时从 application.properties
或 application.yml
中读取配置属性。不过,可以使用 @PropertySource
来加载自定义 YAML 文件。
熟悉了 YAML 文件后,来看看如何在 Spring Boot 中将 YAML 属性注入到 Map
中。
3、将 YAML 属性注入到 Map
通过 @ConfigurationProperties
注解,Spring Boot 可轻松地将配置文件中的外部属性直接注入 Java 对象。
首先,在 application.yml
中定义一些 Key/Value 属性:
server:
application:
name: InjectMapFromYAML
url: http://injectmapfromyaml.dev
description: How To Inject a map from a YAML File in Spring Boot
config:
ips:
- 10.10.10.10
- 10.10.10.11
- 10.10.10.12
- 10.10.10.13
filesystem:
- /dev/root
- /dev/md2
- /dev/md4
users:
root:
username: root
password: rootpass
guest:
username: guest
password: guestpass
配置属性如上,接下来尝试将 application
映射为一个简单的 Map<String, String>
。将 config
注入为一个 Map<String, List<String>>
,将 users
映射为一个 Map
,其中 Key 是 String
,Value 是自定义(Credential
)对象。
创建一个 Bean 类 ServerProperties
,以封装将配置属性绑定到 Map
的逻辑:
@Component
@ConfigurationProperties(prefix = "server")
public class ServerProperties {
private Map<String, String> application;
private Map<String, List<String>> config;
private Map<String, Credential> users;
// Get、Set
public static class Credential {
private String username;
private String password;
// Get、Set
}
}
如你所见,用 @ConfigurationProperties
注解了 ServerProperties
类,以告诉 Spring 将所有带有指定前缀(prefix)的属性映射到 ServerProperties
对象中。
最后,测试 YAML 属性是否被正确注入为 Map
:
@RunWith(SpringRunner.class)
@SpringBootTest
class MapFromYamlIntegrationTest {
@Autowired
private ServerProperties serverProperties;
@Test
public void whenYamlFileProvidedThenInjectSimpleMap() {
assertThat(serverProperties.getApplication())
.containsOnlyKeys("name", "url", "description");
assertThat(serverProperties.getApplication()
.get("name")).isEqualTo("InjectMapFromYAML");
}
@Test
public void whenYamlFileProvidedThenInjectComplexMap() {
assertThat(serverProperties.getConfig()).hasSize(2);
assertThat(serverProperties.getConfig()
.get("ips")
.get(0)).isEqualTo("10.10.10.10");
assertThat(serverProperties.getUsers()
.get("root")
.getUsername()).isEqualTo("root");
}
}
4、@ConfigurationProperties 和 @Value
现在来比较一下 @ConfigurationProperties
和 @Value
。
尽管这两种注解都可用于从配置文件注入属性,但它们之间却有很大的不同。这两个注解的主要区别在于各自的用途不同。
简而言之,@Value
允许通过 Key 直接注入特定属性值。然而,@ConfigurationProperties
注解将多个属性绑定到一个特定对象,并通过对象提供对属性的访问。
一般来说,在注入配置数据时,Spring 建议使用 @ConfigurationProperties
而不是 @Value
。@ConfigurationProperties
提供了一种将配置属性集中并分组到结构化对象中的好方法,可以将其注入到其他 Bean 中。
5、总结
本文介绍了如何在 Spring Boot 中把 YAML 属性绑定到 Map
,还介绍了 @ConfigurationProperties
和 @Value
之间的区别。
Ref:https://www.baeldung.com/spring-yaml-inject-map