首页 > 解决方案 > 使用 Spring Boot 2 以编程方式将 yaml 字符串转换为 ConfigurationProperties

问题描述

我有一个第三方库,它提供了一个用于 ConfigurationProperties 的类,例如:

@ConfigurationProperties(prefix = "foo")
public class AnimalProperties {

    private List<Treats> treats = new ArrayList<>();
...
}

在 Spring Boot 2 中,将 Yaml 字符串(以编程方式构造)绑定到 AnimalProperties 实例的最简单方法是什么?例如,给定字符串:

treats:
  -
    name: treat1
    flavour: sweet
  -
    name: treat2
    flavour: sour

在 Spring Boot 1.x 中,这可以使用 YamlConfigurationFactory 完成,但是在 Spring Boot 2 中不再存在。

例如:

    YamlConfigurationFactory<AnimalProperties> animalConfigFactory = new YamlConfigurationFactory<>(
            AnimalProperties.class);
    animalConfigFactory.setYaml("{ treats: " + treatYalm + " }");
    try {
        animalConfigFactory.afterPropertiesSet();
        treats.addAll(animalConfigFactory.getObject().getTreats());
    }
    ...

标签: javaspringspring-boot

解决方案


YamlConfigurationFactory不幸的是,在 Spring Boot 2.x中没有直接替代品。YamlConfigurationFactory实际上,从查看源代码来看,至少从我的研究来看,Spring Boot 内部的任何地方似乎都没有实际使用它。

但是YamlConfigurationFactory在内部只使用snakeyaml,所以可能是这样的:

import org.yaml.snakeyaml.Yaml;

Yaml yaml = new Yaml();
String myYamlString = "...."
AnimalProperties animalProps = yaml.loadAs(myYamlString, AnimalProperties.class)

真正唯一的缺点是您丢失了afterPropertiesSet由实现InitializingBean接口执行的验证。


如果该 yml 字符串刚刚在您的application.ymlas 中定义:

foo:
  treats:
    -
      name: treat1
      flavour: sweet
    -
      name: treat2
      flavour: sour

然后你可以像使用任何 bean 一样注入它:

@Service
public class ExampleService {
    private final AnimalProperties animalProperties;

    public ExampleService(AnimalProperties animalProperties) {
        this.animalProperties = animalProperties;
    }
}

Spring 将在创建时在启动时进行 bean 验证AnimalProperties


推荐阅读