在 Spring Boot 中将 YAML 转换成对象列表
1、概览
本文将带你了解如何在 YAML 中定义列表,以及如何在 Spring Boot 中把 YAML 列表映射为 Java List
对象。
2、回顾一下 YAML 中的列表
简而言之,YAML 是一种人类可读的数据序列化标准,为编写配置文件提供了一种简洁明了的方法。YAML 的优点在于它支持多种数据类型,如 List
、Map
和标量(Scalar)类型。
YAML 列表中的元素使用 -
字符定义,它们的缩进级别相同:
yamlconfig:
list:
- item1
- item2
- item3
- item4
相比之下,在 properties 中定义列表则使用的是索引值:
yamlconfig.list[0]=item1
yamlconfig.list[1]=item2
yamlconfig.list[2]=item3
yamlconfig.list[3]=item4
与 properties 文件相比,YAML 的分层性质大大提高了可读性。YAML 的另一个功能是可以为不同的 Spring Profile 定义不同的属性。从 Boot 2.4.0 版开始,properties 文件也可以这样做。
Spring Boot 为 YAML 配置提供了开箱即用的支持。根据设计,Spring Boot 会在启动时从 application.yml
中加载配置属性,无需任何额外工作。
3、将 YAML 列表绑定至简单的 List
Spring Boot 提供了 @ConfigurationProperties
注解,以简化将外部配置数据映射到对象模型的逻辑。
接下来看看如何使用 @ConfigurationProperties
将 YAML 列表绑定到 List<Object>
中。
首先在 application.yml
中定义一个简单的列表:
application:
profiles:
- dev
- test
- prod
- 1
- 2
然后,创建一个简单的 ApplicationProps
POJO,用于将 YAML 列表绑定到 List<Object>
:
@Component
@ConfigurationProperties(prefix = "application")
public class ApplicationProps {
private List<Object> profiles;
// get、set 方法
}
ApplicationProps
类需要用 @ConfigurationProperties
来装饰,表示将带有指定前缀的所有 YAML 属性映射到 ApplicationProps
对象。
要绑定 profiles
列表,只需定义一个 List
类型的字段,剩下的就交给 @ConfigurationProperties
注解来处理。
使用 @Component
将 ApplicationProps
类注册为普通的 Spring Bean。因此,可以像其他 Spring Bean 一样将其注入到其他类中。
最后,将 ApplicationProps
Bean 注入测试类,并验证配置文件 YAML 列表是否被正确注入为 List<Object>*
:
@ExtendWith(SpringExtension.class)
@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class)
@EnableConfigurationProperties(value = ApplicationProps.class)
class YamlSimpleListUnitTest {
@Autowired
private ApplicationProps applicationProps;
@Test
public void whenYamlList_thenLoadSimpleList() {
assertThat(applicationProps.getProfiles().get(0)).isEqualTo("dev");
assertThat(applicationProps.getProfiles().get(4).getClass()).isEqualTo(Integer.class);
assertThat(applicationProps.getProfiles().size()).isEqualTo(5);
}
}
4、将 YAML 列表绑定到复杂的 List
来看看如何将嵌套的 YAML 列表注入到复杂结构的 List
中。
首先,在 application.yml
中添加一些嵌套列表:
application:
// ...
props:
-
name: YamlList
url: http://yamllist.dev
description: Mapping list in Yaml to list of objects in Spring Boot
-
ip: 10.10.10.10
port: 8091
-
email: support@yamllist.dev
contact: http://yamllist.dev/contact
users:
-
username: admin
password: admin@10@
roles:
- READ
- WRITE
- VIEW
- DELETE
-
username: guest
password: guest@01
roles:
- VIEW
本例中,我们要把 props
属性绑定到 List<Map<String, Object>>
中,把 users
映射到 User
对象的 List
中。
由于 props
条目的每个元素都拥有不同的 Key,因此可以将其注入为 List<Map<String, Object>>
表。
然而,在 users
列表下,所有项目的 Key 都相同,因此为了简化映射,可以创建一个专门的 User
类,将 Key 封装为字段:
public class ApplicationProps {
// ...
private List<Map<String, Object>> props;
private List<User> users;
// get / set 方法
public static class User {
private String username;
private String password;
private List<String> roles;
// get / set 方法
}
}
现在,来验证嵌套的 YAML 列表是否已正确映射:
@ExtendWith(SpringExtension.class)
@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class)
@EnableConfigurationProperties(value = ApplicationProps.class)
class YamlComplexListsUnitTest {
@Autowired
private ApplicationProps applicationProps;
@Test
public void whenYamlNestedLists_thenLoadComplexLists() {
assertThat(applicationProps.getUsers().get(0).getPassword()).isEqualTo("admin@10@");
assertThat(applicationProps.getProps().get(0).get("name")).isEqualTo("YamlList");
assertThat(applicationProps.getProps().get(1).get("port").getClass()).isEqualTo(Integer.class);
}
}
5、总结
本文介绍了如何把 YAML 中的列表映射为 Java List
,以及如何在 Spring Boot 中自动把属性绑定到 POJO 类。
Ref:https://www.baeldung.com/spring-boot-yaml-list