admin管理员组

文章数量:1415491

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();
  }
}

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();
  }
}
Share Improve this question edited Feb 21 at 4:23 seenukarthi 8,68410 gold badges50 silver badges74 bronze badges asked Feb 21 at 3:36 VikrantVikrant 751 gold badge1 silver badge9 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 4

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

There is no need to provide prefix here. Just remove prefix.

@Component
@ConfigurationProperties
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
  }
}

If you want to use simple "input" prefix, which is trying to pickup properties form the root, you will need to update your application.properties file content with .properties prefix, like @rahulP suggested.

But, as far as you are trying to map ServiceModel - better will be to update prefix and properties with input.service prefix, see https://docs.spring.io/spring-boot/reference/features/external-config.html#features.external-config.typesafe-configuration-properties:

@ConfigurationProperties(prefix = "input.services")

application.properties:

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

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

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

Also I think you are missing default contructor in ServiceModel, which is required for Spring.

@rahulP's method works.

The reason for this error is that in the ServiceModelConfiguration class, properties is a Map<String, ServiceModel>. This means that Spring Boot would expect to have a node in the configuration file that corresponds to the properties and that contains multiple key-value pairs under this node, each corresponding to a ServiceModel.

本文标签: javaSpringBoot not able to initialize ConfigurationProperties for Map propertiesStack Overflow