51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

在 Spring Boot 中把 YAML 属性绑定到 Map

1、概览 {#1概览}

本文将带你了解如何在 Spring Boot 中把 YAML 属性注入到 Map

2、Spring 中的 YAML 文件 {#2spring-中的-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.propertiesapplication.yml 中读取配置属性。不过,可以使用 @PropertySource 来加载自定义 YAML 文件。

熟悉了 YAML 文件后,来看看如何在 Spring Boot 中将 YAML 属性注入到 Map 中。

3、将 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 {#4configurationproperties-和-value}

现在来比较一下 @ConfigurationProperties@Value

尽管这两种注解都可用于从配置文件注入属性,但它们之间却有很大的不同。这两个注解的主要区别在于各自的用途不同。

简而言之,@Value 允许通过 Key 直接注入特定属性值。然而,@ConfigurationProperties 注解将多个属性绑定到一个特定对象,并通过对象提供对属性的访问。

一般来说,在注入配置数据时,Spring 建议使用 @ConfigurationProperties 而不是 @Value@ConfigurationProperties 提供了一种将配置属性集中并分组到结构化对象中的好方法,可以将其注入到其他 Bean 中。

5、总结 {#5总结}

本文介绍了如何在 Spring Boot 中把 YAML 属性绑定到 Map,还介绍了 @ConfigurationProperties@Value 之间的区别。


Ref:https://www.baeldung.com/spring-yaml-inject-map

赞(1)
未经允许不得转载:工具盒子 » 在 Spring Boot 中把 YAML 属性绑定到 Map