GaZ
GaZ

Reputation: 2406

Programatically convert yaml string to ConfigurationProperties with Spring Boot 2

I have a third party library which provides a class used for ConfigurationProperties, such as the following:

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

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

In Spring Boot 2, what is the easiest way to bind a Yaml string (constructed programatically) to an instance of AnimalProperties? For example, given the string:

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

In Spring Boot 1.x this could be done using the YamlConfigurationFactory, however this is no longer present in Spring Boot 2.

For example:

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

Upvotes: 1

Views: 1607

Answers (1)

Cisco
Cisco

Reputation: 23070

Unfortunately there is no direct replacement for YamlConfigurationFactory in Spring Boot 2.x. In fact, from looking at the source, it doesn't appear that YamlConfigurationFactory is actually used any where internally in Spring Boot, at least from my research.

However YamlConfigurationFactory internally just uses snakeyaml, so maybe something like:

import org.yaml.snakeyaml.Yaml;

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

Really the only downside is that you lose the validation that was performed by afterPropertiesSet that comes from implementing the InitializingBean interface.


If that yml string is just defined in your application.yml as:

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

then you can just inject it as with any bean:

@Service
public class ExampleService {
    private final AnimalProperties animalProperties;

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

Spring will do bean validation at start-up when the AnimalProperties gets created.

Upvotes: 2

Related Questions