[英]Spring Bean Wiring
我正在學習Spring的基礎知識,現在我正在研究Beans /接線。 這個問題可能沒有意義,這只是我在閱讀/嘗試Craig Walls的“Spring into Action”一書中的一些例子之后想到的。 說有這個界面。
public interface CompactDisc {
void play()
}
我有兩個實現此接口的類。
public class HybridTheory implements CompactDisc { }
public class Meteora implements CompactDisc { }
我的配置類使用組件掃描並從這兩個類創建bean。 現在,如果我有一個具有光盤實例的測試類,並使用自動連接進行連線
public class myTest {
@Autowired
private CompactDisc cd;
}
會有問題嗎? 我的問題是,你如何連接它,以便它使用一個bean而不是另一個? 或者這不是真實情況/我應該創建特定類的屬性,而不是接口的屬性? 我想我只是難以繞着布線纏繞我的腦袋。
每當遇到有多個實現相同接口的情況時,您可以采取的方法很少。
1.使用@Qualifier注釋
如果您使用類路徑掃描,您的類可能如下所示:
@Component
public class HybridTheory implements CompactDisc { }
@Component
public class Meteora implements CompactDisc { }
每個Spring bean都獲取一個由容器分配的id,默認情況下它是一個以較小字母開頭的類名。 如果這兩個組件將是:
hybridTheory
meteora
您可能還希望通過將name
參數傳遞給@Component注釋來選擇自定義名稱,例如: @Component("myFavLinkinParkAlbum")
。
然后,每當你自動裝配CompactDisc
bean時,你都可以傳遞@Qualifier注釋並告訴Spring你想到的是哪個bean。
@Service
class Player {
private final CompactDisc compactDisc;
// note that starting from Spring 4.3
// you can omit @Autowired annotation from constructor
Player(@Qualifier("hybridTheory") CompactDisc compactDisc) {
this.compactDisc = compactDisc;
}
}
2.將您的一個bean標記為@Primary
如果在大多數注射點注射總是相同的豆而另一個很少使用,您可以考慮使用@Primary標記前者。
@Component
@Primary
public class HybridTheory implements CompactDisc { }
每當Spring發現有多個bean匹配注入點時,它將注入一個用@Primary注釋的bean 。 請注意,如果有多個使用@Primary注釋的bean並且實現了注入點中使用的接口,問題仍然存在。
3.使用Java配置
雖然@Qualifier和@Primary有時會解決問題,但您可能會發現要了解注入了哪些實現,您需要通過源代碼大量旅行。 有時候更干凈的方法是從類中刪除@Component (或其他構造型注釋)並使用Java配置聲明bean:
public class HybridTheory implements CompactDisc { }
public class Meteora implements CompactDisc { }
@Configuration
class RecordsConfiguration {
@Bean
CompactDisc hybridTheory() {
return new HybridTheory();
}
@Bean
CompactDisc meteora() {
return new Meteora();
}
@Bean
Player player() {
return new Player(meteora());
}
}
選擇最適合您用例的產品!
一種簡單而優雅的方法是盡可能使用byType 。 當那是不可能的,可以使用的綽號方法。
使用它的一種方法是手動命名bean - 然后在更改類名后bean名稱不會有所不同。 請注意,只有在具有相同類型的多個實現時才應使用命名bean,否則不需要命名。 在下面的示例中,命名是注釋的一部分,例如@Component("hybridTheory")
。 這意味着您可以將HybridTheory
的類名HybridTheory
為您想要的任何名稱,並且bean名稱仍然是hybridTheory
。
當您通過名稱注入某些內容時 ,可以使用@Qualifier
批注指定所需的命名bean。 我個人更喜歡@Resource
因為你可以在構造函數中使用@Qualifier
(我更喜歡構造函數注入而不是基於setter和field的注入)。
你不應該注入的具體類型-這就是依賴注入是怎么一回事。 其他人(即Spring)將為您處理對象創建;)
public interface CompactDisc {
void play();
}
@Component
class CompactDiscPlayer {
@Autowired
CompactDiscPlayer(@Qualifier("hybridTheory") final CompactDisc compactDisc) {
// The bean of type HybridTheory will be used
compactDisc.play();
}
}
@Component("hybridTheory")
class HybridTheory implements CompactDisc {
public void play() {
System.out.println(getClass().getSimpleName());
}
}
@Component("meteora")
class Meteora implements CompactDisc {
public void play() {
System.out.println(getClass().getSimpleName());
}
}
Spring的文檔描述了各種選項在這里 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.