[英]Spring @Autowire many beans
我正在編寫一個工廠類,它根據給定的參數將返回接口的各種實現:
class Factory {
public MyType getType(String param) {
if (param.equals("A")) {
return new MyTypeA();
} else if (param.equals("B")) {
return new MyTypeB();
}
}
現在我想利用 Spring 的依賴注入功能而不是new
。 我想使用基於@Annotation 的自動裝配。
首先想到的是在字段上使用@Autowire
,如下所示:
class Factory {
@Autowired
private MyTypeA myTypeA;
@Autowired
private MyTypeB myTypeB;
public MyType getType(String param) {
if (param.equals("A")) {
return myTypeA;
} else if (param.equals("B")) {
return myTypeB;
}
}
但是我記得不建議使用字段自動裝配,因為很難對此類類進行單元測試。
接下來我可以嘗試使用 setter 級別的自動裝配來進行測試:
class Factory {
private MyTypeA myTypeA;
private MyTypeB myTypeB;
public MyType getType(String param) {
if (param.equals("A")) {
return myTypeA;
} else if (param.equals("B")) {
return myTypeB;
}
@Autowired
public void setMyTypeA(MyTypeA a) {
this.myTypeA = a;
}
@Autowired
public void setMyTypeB(MyTypeB b) {
this.myTypeB = b;
}
}
好的,這看起來更好,但是等等,還有更多 - 我希望我的類是不可變的,所以我希望我的私有字段是最終的,並且只在構造函數時填充。 所以接下來我可以嘗試的是基於構造函數的注入:
class Factory {
private final MyTypeA myTypeA;
private final MyTypeB myTypeB;
public Factory(MyTypeA myTypeA, MyTypeB myTypeB) {
this.myTypeA = myTypeA;
this.myTypeB = myTypeB;
}
public MyType getType(String param) {
if (param.equals("A")) {
return myTypeA;
} else if (param.equals("B")) {
return myTypeB;
}
}
看起來不錯,但問題來了——如果我有 20 種不同的類型,我可以根據參數值從這個工廠返回,我不能創建一個 20 參數的構造函數。
請建議,在這種情況下最好的方法是什么(試圖避免基於 xml 的自動裝配)。
謝謝
假設您所有的MyType
類已經是 Spring 管理的 bean,您可以簡單地使用一個列表。
假設
@Configuration
class Config{
@Bean
public MyType myTypeA() {
return new MyTypeA();
}
@Bean
public MyType myTypeB() {
return new MyTypeB();
}
}
然后,您可以將 List 自動裝配到Factory
:
@Bean
public Factory factory(List<MyType> myTypes) {
return new Factory(myTypes);
}
此列表將包含myTypeA
和myTypeB
。 從那里,我可能會在Factory
做這樣的事情:
public class Factory {
final Map<String, MyType> myTypes;
public Factory(List<MyType> types) {
//build map of types with "param" as the key
}
public MyType getType(String param) {
return myTypes.get(param);
}
}
您可以繼續遵循此方法。
class Factory {
@Autowired
private MyTypeA myTypeA;
@Autowired
private MyTypeB myTypeB;
public MyType getType(String param) {
if (param.equals("A")) {
return myTypeA;
} else if (param.equals("B")) {
return myTypeB;
}
}
現在要解決在測試用例中注入模擬的問題,您只需使用 @InjectMocks 注釋即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.