javaspringspring-bootspring-mvc

SpringBoot not able to initialize @ConfigurationProperties for Map properties


In SpringBoot, I am trying to read the application.properties to Map<String, ServiceModel>, which should be

application.properties

input.default.host=Default
input.default.ip=127.0.0.1
input.default.desc=Default Desc

input.serviceA.host=ServiceA
input.serviceA.ip=192.168.21.1
input.serviceA.desc=ServiceA Desc

input.serviceB.host=ServiceB
input.serviceB.ip=192.168.21.22
input.serviceB.desc=ServiceB Desc

Whenever I try to print it using getServiceProperty(String key) the Map properties are always null, as if they are not initialized.

Here are the details of the classes -

@Component
@ConfigurationProperties(prefix = "input")
public class ServiceModelConfiguration {
  private Map<String, ServiceModel> properties;

  public Map<String, ServiceModel> getProperties() {
    return properties;
  }
  public void setProperties(Map<String, ServiceModel> properties) {
    this.properties = properties;
  }

  public ServiceModel getServiceProperty(String key) {
    ServiceModel specificProperty = properties.get(key);
    return specificProperty;
  }

  public static class ServiceModel {
    private String host;
    private String ip;
    private String desc;

    public ServiceModel(String host, String ip, String desc) {
      this.host = host;
      this.ip = ip;
      this.desc = desc;
    }

    // Getters
    // Setters
  }
}
@Service
public class PrintServices {
  private final ServiceModelConfiguration serviceModelConfiguration;

  @Autowired
  public PrintServices(ServiceModelConfiguration serviceModelConfiguration) {
    this.serviceModelConfiguration = serviceModelConfiguration;
  }
  public void printAllServiceProperties() {
    System.out.println("Host: "
        + serviceModelConfiguration.getServiceProperty("serviceA").getHost());
    System.out.println("IP: "
        + serviceModelConfiguration.getServiceProperty("serviceA").getIp());
    System.out.println("Desc: "
        + serviceModelConfiguration.getServiceProperty("serviceA").getDesc());
  }
}
@SpringBootApplication
@EnableConfigurationProperties(ServiceModelConfiguration.class)
public class ConfigApplication implements CommandLineRunner {
  @Autowired private PrintServices printServices;

  public static void main(String[] args) {
    SpringApplication.run(ConfigApplication.class, args);
  }

  @Override
  public void run(String... args) throws Exception {
    printServices.printAllServiceProperties();
  }
}

Solution

  • keep your propperties like this. The @ConfigurationProperties(prefix = "input") maps only direct fields inside ServiceModelConfiguration.

    input.properties.default.host=Default
    input.properties.default.ip=127.0.0.1
    input.properties.default.desc=Default Desc
    
    input.properties.serviceA.host=ServiceA
    input.properties.serviceA.ip=192.168.21.1
    input.properties.serviceA.desc=ServiceA Desc
    
    input.properties.serviceB.host=ServiceB
    input.properties.serviceB.ip=192.168.21.22
    input.properties.serviceB.desc=ServiceB Desc