checketts
checketts

Reputation: 15003

How can I read in a list of objects from yaml using Spring's PropertiesConfigurationFactory?

If I have a set of properties, I understand that Springboot's relaxed data binder will read in a list of properties (or yaml) and populate the matching object. Like so:

Properties props = new Properties();
props.put("devices.imports[0]","imp1");
props.put("devices.imports[1]","imp2");
props.put("devices.definitions[0].id","first");
props.put("devices.definitions[1].id", "second");

DeviceConfig conf = new DeviceConfig();
PropertiesConfigurationFactory<DeviceConfig> pcf = new PropertiesConfigurationFactory<>(conf);
pcf.setProperties(props);

conf = pcf.getObject();
assertThat(conf.getDefinitions()).hasSize(2); //Definitions is coming in as 0 instead of the expected 2

DeviceConfig looks like this:

@ConfigurationProperties(prefix="devices")
public class DeviceConfig {

    private List<String> imports = new ArrayList<>();
    private List<DeviceDetailsProperties> definitions = new ArrayList<>();

    public List<String> getImports() {
        return this.imports;
    }

    public List<DeviceDetailsProperties> getDefinitions() {
        return definitions;
    }

    public void setImports(List<String> imports) {
        this.imports = imports;
    }

    public void setDefinitions(List<DeviceDetailsProperties> definitions) {
        this.definitions = definitions;
    }
}

DeviceDetailsProperties just has an id field with getters/setters.

Strangely neither the definitions (objects) or imports (Strings) are getting populated.

Using SpringBoot 1.2.0.RELEASE

Upvotes: 0

Views: 1154

Answers (1)

checketts
checketts

Reputation: 15003

When using the PropertiesConfigurationFactory in a manual way like this, it won't automatically use the prefix value in the annotation.

Add a targetName like so:

pcf.setTargetName("devices");

The corrected code would be:

Properties props = new Properties();
props.put("devices.imports[0]","imp1");
props.put("devices.imports[1]","imp2");
props.put("devices.definitions[0].id","first");
props.put("devices.definitions[1].id", "second");

DeviceConfig conf = new DeviceConfig();
PropertiesConfigurationFactory<DeviceConfig> pcf = new PropertiesConfigurationFactory<>(conf);
pcf.setProperties(props);
pcf.setTargetName("devices"); // <--- Add this line

conf = pcf.getObject();
assertThat(conf.getDefinitions()).hasSize(2); 

Upvotes: 1

Related Questions