1. 概述
本文将深入探讨 如何在 Spring Boot 中将 YAML 配置中的列表映射为 Java 的 List
类型。
我们会先快速回顾 YAML 中列表的定义方式,然后重点讲解如何将 YAML 列表绑定到对象列表(包括简单类型和复杂嵌套结构)。这在实际项目中非常常见,比如配置多数据源、多个第三方服务地址等场景,掌握这个技巧能让你的配置更清晰、代码更优雅。
2. YAML 列表语法快速回顾
YAML 是一种人类可读的数据序列化格式,特别适合用来写配置文件。✅ 它支持多种数据结构,比如列表(List)、映射(Map)和基本类型。
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 文件很快就会变得难以维护。
值得一提的是,Spring Boot 原生支持 YAML 配置,启动时会自动加载 application.yml
,无需额外配置。从 Spring Boot 2.4.0 开始,properties 文件也支持多 profile 配置,但 YAML 依然是主流选择。
3. 将 YAML 列表绑定到简单对象列表
Spring Boot 提供了 @ConfigurationProperties
注解,可以将外部配置自动绑定到 Java 对象,极大简化配置管理。
我们先在 application.yml
中定义一个包含混合类型的列表:
application:
profiles:
- dev
- test
- prod
- 1
- 2
接着创建一个 POJO 类来接收这个列表:
@Component
@ConfigurationProperties(prefix = "application")
public class ApplicationProps {
private List<Object> profiles;
// getter 和 setter
public List<Object> getProfiles() {
return profiles;
}
public void setProfiles(List<Object> profiles) {
this.profiles = profiles;
}
}
关键点:
- ✅ 使用
@ConfigurationProperties(prefix = "application")
指定配置前缀 - ✅ 字段类型为
List<Object>
,Spring 会自动完成类型推断(字符串、整数等) - ✅ 加上
@Component
注解,使其成为 Spring 容器管理的 Bean,方便注入使用
最后写个测试验证是否正确加载:
@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);
}
}
测试通过,说明 dev
、test
等字符串和 1
、2
这样的数字都被正确识别并放入 List<Object>
中。
4. 将 YAML 列表绑定到复杂对象列表
更常见的场景是处理嵌套结构,比如一组服务配置或用户列表。下面我们看如何处理这类复杂列表。
先在 application.yml
中添加嵌套列表:
application:
profiles:
- dev
- test
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: admin@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
类来封装
修改 ApplicationProps
类:
@Component
@ConfigurationProperties(prefix = "application")
public class ApplicationProps {
private List<Object> profiles;
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
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<String> getRoles() {
return roles;
}
public void setRoles(List<String> roles) {
this.roles = roles;
}
}
// 其他 getter/setter
public List<Object> getProfiles() {
return profiles;
}
public void setProfiles(List<Object> profiles) {
this.profiles = profiles;
}
public List<Map<String, Object>> getProps() {
return props;
}
public void setProps(List<Map<String, Object>> props) {
this.props = props;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
}
写个测试验证绑定结果:
@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);
}
}
测试通过,说明:
- ✅
users
成功映射为List<User>
,类型安全 - ✅
props
作为异构数据,用List<Map<String, Object>>
接收也很灵活 - ✅ 数字类型(如
port: 8091
)自动识别为Integer
5. 总结
本文演示了在 Spring Boot 中处理 YAML 列表的两种典型方式:
- ✅ 简单列表:直接用
List<Object>
或List<String>
接收 - ✅ 复杂列表:通过定义内部类或 Map 结构实现灵活绑定
关键技巧:
- 使用
@ConfigurationProperties
+@Component
实现配置自动注入 - 合理利用
List<Map<String, Object>>
处理结构不一致的列表 - 对于结构一致的数据,定义 POJO 提升类型安全和可维护性
⚠️ 踩坑提示:如果配置类没有被 Spring 扫描到,记得检查是否加了 @Component
或在主类上加 @EnableConfigurationProperties
。
完整代码示例可在 GitHub 获取:https://github.com/eugenp/tutorials/tree/master/spring-boot-modules/spring-boot-properties-2