baeldung 2025-03-26
1. 概述
在本篇简短教程中,我们将深入探讨如何在 Spring Boot 中将 YAML 列表映射为 Java 的 List 对象。
首先,我们会回顾一下如何在 YAML 中定义列表。
接着,我们将深入研究如何将 YAML 列表绑定到对象列表(List of objects)。
2. YAML 列表快速回顾
简而言之,YAML 是一种人类可读的数据序列化标准,它提供了一种简洁清晰的方式来编写配置文件。YAML 的优点在于支持多种数据类型,如列表(Lists)、映射(Maps)和标量类型(scalar types)。
YAML 列表中的元素使用 - 字符定义,并且所有元素需保持相同的缩进级别:
yamlconfig:
list:
- item1
- item2
- item3
- item4
作为对比,基于 properties 文件的等效写法需要使用索引:
yamlconfig.list[0]=item1
yamlconfig.list[1]=item2
yamlconfig.list[2]=item3
yamlconfig.list[3]=item4
实际上,YAML 的层次结构显著提升了可读性,相较于 properties 文件更具优势。YAML 的另一个有趣特性是支持为不同的 Spring 配置文件(profiles)定义不同属性。从 Spring Boot 2.4.0 版本开始,properties 文件也支持这一功能。
值得一提的是,Spring Boot 对 YAML 配置提供了开箱即用的支持。默认情况下,Spring Boot 在启动时会自动加载 application.yml 中的配置,无需额外操作。
3. 将 YAML 列表绑定到简单对象列表
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;
// getter 和 setter 方法
}
ApplicationProps 类需要使用 @ConfigurationProperties 注解,以表明其意图是将指定前缀下的所有 YAML 属性映射到该类的实例中。
为了绑定 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 列表绑定到复杂对象列表
现在,我们进一步探讨如何将嵌套的 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 对象的列表。
由于 props 中每个元素包含不同的键(key),我们可以将其注入为 Map 的列表。有关如何从 YAML 文件注入 Map 的详细说明,请参阅我们的相关文章。
然而,对于 users,所有条目都具有相同的键,因此为了简化映射,我们可以创建一个专用的 User 类来封装这些键作为字段:
public class ApplicationProps {
// ...
private List<Map<String, Object>> props;
private List<User> users;
// getters and setters
public static class User {
private String username;
private String password;
private List<String> roles;
// getters and setters
}
}
现在我们验证嵌套的 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。
同时,我们也了解了如何将复杂列表绑定到自定义的 POJO 对象。