问题
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!
回答1:
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;
}
回答2:
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());
}
}
回答3:
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.
回答4:
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:
来源:https://stackoverflow.com/questions/49422952/spring-boot-multiple-similar-configurationproperties-with-different-prefixes