在 Spring Boot 中将 YAML 转换为对象列表

更新于 2025-12-30

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 注解会自动完成其余工作。

注意:我们使用 @ComponentApplicationProps 注册为普通的 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 对象。