35

I'm using Spring Boot and have two very similar services which I'd like to configure in my application.yml.

The configuration looks roughly like this:

serviceA.url=abc.com
serviceA.port=80

serviceB.url=def.com
serviceB.port=8080

Is it possible to create one class annotated with @ConfigurationProperties and set the prefix at the injection point?

e.g.

@Component
@ConfigurationProperties
public class ServiceProperties {
   private String url;
   private String port;

   // Getters & Setters
}

and then in the Services itself:

public class ServiceA {

   @Autowired
   @SomeFancyAnnotationToSetPrefix(prefix="serviceA")
   private ServiceProperties serviceAProperties;

   // ....
}

Unfortunately I haven't found something in the documentation about such a feature... Thank you very much for your help!

4 Answers 4

36

I achieved almost same thing that you trying. first, register each properties beans.

@Bean
@ConfigurationProperties(prefix = "serviceA")
public ServiceProperties  serviceAProperties() {
    return new ServiceProperties ();
}

@Bean
@ConfigurationProperties(prefix = "serviceB")
public ServiceProperties  serviceBProperties() {
    return new ServiceProperties ();
}

and at service(or someplace where will use properties) put a @Qualifier and specified which property would be auto wired .

public class ServiceA {
    @Autowired
    @Qualifier("serviceAProperties")
    private ServiceProperties serviceAProperties;

}
3
  • Thanks a lot! This is exactly what I was looking for! You only need to set the @Qualifier at the Bean definition too, I suppose.
    – nioe
    Commented Mar 22, 2018 at 7:59
  • 6
    I'm trying to use the same but I'm getting the bean with all the properties set as null. What am I missing?
    – Nishant
    Commented Nov 26, 2018 at 7:06
  • @Nishant It could happen if Spring can't resolve property definition with specified prefix. Try to check property source location. It could happen if Spring can't resolve property definition with specified prefix. And Spring will not call setters silently. To check this you can use Value annotation and try to pass one of the property as parameter to bean definition method. If property is unreachable the context will not be initialized.
    – piphonom
    Commented Sep 2, 2021 at 12:34
9

Following this post Guide to @ConfigurationProperties in Spring Boot you can create a simple class without annotations:

public class ServiceProperties {
   private String url;
   private String port;

   // Getters & Setters
}

And then create the @Configuration class using @Bean annotation:

@Configuration
@PropertySource("classpath:name_properties_file.properties")
public class ConfigProperties {

    @Bean
    @ConfigurationProperties(prefix = "serviceA")
    public ServiceProperties serviceA() {
        return new ServiceProperties ();
    }

    @Bean
    @ConfigurationProperties(prefix = "serviceB")
    public ServiceProperties serviceB(){
        return new ServiceProperties ();
    }
}

Finally you can get the properties as follow:

@SpringBootApplication
public class Application implements CommandLineRunner {

    @Autowired
    private ConfigProperties configProperties ;

    private void watheverMethod() {
        // For ServiceA properties
        System.out.println(configProperties.serviceA().getUrl());

        // For ServiceB properties
        System.out.println(configProperties.serviceB().getPort());
    }
}
0

Javvanos example worked perfektly, except for JavaBean Validation.

I've had an annotation @NotNull on one of the properties:

public class ServiceProperties {
   @NotNull
   private String url;
   private String port;

   // Getters & Setters

}

As a consequence, the application startup failed with following error message:

***************************
APPLICATION FAILED TO START
***************************

Description:

Binding to target ch.sbb.hop.commons.infrastructure.hadoop.spark.SparkJobDeployerConfig@730d2164 failed:

    Property: url
    Value: null
    Reason: may not be null


Action:

Update your application's configuration

After removing the annotation, the application startet up with correct property binding. In conclusion, I think there is an issue with JavaBean Validation not getting the correctly initialized instance, maybe because of missing proxy on configuration methods.

-5

The @ConfigurationProperties anotation has the field to set prefix configulation. Here is my example:

@Component
@ConfigurationProperties(prefix = "b2gconfig")
public class B2GConfigBean {
    private  String account;

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    private  String key;
}

And my application.properties file: enter image description here

Not the answer you're looking for? Browse other questions tagged or ask your own question.