![](/img/trans.png)
[英]Spring boot inject bean at runtime based on request endpoint/request param
[英]spring boot starter inject bean based on property
最近,我正在開發一個彈簧啟動啟動器,為客戶端代碼提供ServiceA
。 我想提供以下配置屬性:
my.namespace.serviceA=impl1 #or other implemtations
my.namespace.serviceA.impl1.prop1=ServiceAImpl1Prop1Val
my.namespace.serviceA.impl1.prop2=ServiceAImpl1Prop2Val
# some other properties of ServiceA
我還為ServiceA
不同實現添加了幾個帶有@ConfigurationProperties
批注的Bean類,因為springboot會將這些屬性自動加載到那些Bean中。
我的入門者想為客戶代碼提供ServiceA
接口,以便可以將其用作:
@Autowire
private ServiceA serviceA;
我需要給出一個工廠方法,例如:
@Bean
public ServiceA serviceA() {
//TODO load my.namespace.serviceA and create the corresponding
//instance of ServiceA Implementation with given properties
}
由於屬性根據不同的實現而有所不同,是否存在一種優雅的方法來利用@ConfigurationProperties
利用屬性bean來實現這種工廠方法?
從外觀上看,您90%都能找到答案。
您可以將ServiceA標記為組件,而不必手動創建Bean,而Spring組件掃描將為您創建Bean。
查看ServiceA的實現
@ConfigurationProperties(prefix = "my.namespace.serviceA.impl1")
@Component
public ConcreteA implements ServiceA {
private String prop1;
private String prop2;
}
基於您想要一個ServiceA實例的事實,您仍然需要使用@ConfigurationProperties
注釋類,但要刪除@Component
。
@ConfigurationProperties(prefix = "my.namespace.serviceA.impl1")
public ConcreteA implements ServiceA {
private String prop1;
public void setProp1(String s) {
prop1 = s;
}
}
您的財產必須至少有二傳手。
然后在配置類中創建bean
@ConfigurationProperties(prefix = "my.namespace")
@Configuration
public SomeConfig {
private String serviceA;
public void setServiceA(String s) {
serviceA = s;
}
@Bean
public ServiceA serviceA() {
if (serviceA.equals("ConcreteA1")) {
return new ConcreteA1();
} else {
return new ConcreteA2();
}
}
}
使用if語句的方法實際上破壞了開放/封閉的原則,而自省是一種更好的方法,但是我認為您可以理解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.