今天帶你瞭解一下 Spring 框架中的 @Qualifier
註解,它解決了哪些問題,以及如何使用它。咱們還將瞭解它與 @Primary
註解的不一樣之處。更多的技術解析請訪問 felord.cnjava
使用 @Autowired
註解是 Spring 依賴注入的絕好方法。可是有些場景下僅僅靠這個註解不足以讓Spring知道到底要注入哪一個 bean。 默認狀況下,@Autowired
按類型裝配 Spring Bean。 若是容器中有多個相同類型的 bean,則框架將拋出 NoUniqueBeanDefinitionException
, 以提示有多個知足條件的 bean 進行自動裝配。程序沒法正確作出判斷使用哪個,下面就是個鮮活的例子:框架
@Component("fooFormatter")
public class FooFormatter implements Formatter {
public String format() {
return "foo";
}
}
@Component("barFormatter")
public class BarFormatter implements Formatter {
public String format() {
return "bar";
}
}
@Component
public class FooService {
@Autowired
private Formatter formatter;
//todo
}
複製代碼
若是咱們嘗試將 FooService
加載到咱們的上下文中,Spring 框架將拋出 NoUniqueBeanDefinitionException
。這是由於 Spring 不知道要注入哪一個 bean。爲了不這個問題,有幾種解決方案。那麼咱們本文要講解的 @Qualifier
註解就是其中之一。跟着小胖哥的節奏往下走。spa
經過使用 @Qualifier
註解,咱們能夠消除須要注入哪一個 bean 的問題。讓咱們從新回顧一下前面的例子,看看咱們如何經過包含 @Qualifier
註釋來指出咱們想要使用哪一個 bean 來解決問題:code
@Component
public class FooService {
@Autowired
@Qualifier("fooFormatter")
private Formatter formatter;
//todo
}
複製代碼
經過將 @Qualifier
註解與咱們想要使用的特定 Spring bean 的名稱一塊兒進行裝配,Spring 框架就能從多個相同類型並知足裝配要求的 bean 中找到咱們想要的,避免讓Spring腦裂。咱們須要作的是@Component或者@Bean註解中聲明的value屬性以肯定名稱。 其實咱們也能夠在 Formatter
實現類上使用 @Qualifier
註釋,而不是在 @Component
或者 @Bean
中指定名稱,也能達到相同的效果:orm
@Component
@Qualifier("fooFormatter")
public class FooFormatter implements Formatter {
public String format() {
return "foo";
}
}
@Component
@Qualifier("barFormatter")
public class BarFormatter implements Formatter {
public String format() {
return "bar";
}
}
複製代碼
還有另外一個名爲 @Primary
的註解,咱們也能夠用來發生依賴注入的歧義時決定要注入哪一個 bean。當存在多個相同類型的 bean 時,此註解定義了首選項。除非另有說明,不然將使用與 @Primary
註釋關聯的 bean 。 咱們來看一個例子:cdn
@Bean
public Employee tomEmployee() {
return new Employee("Tom");
}
@Bean
@Primary
public Employee johnEmployee() {
return new Employee("john");
}
複製代碼
在此示例中,兩個方法都返回相同的 Employee
類型。Spring 將注入的 bean 是方法 johnEmployee
返回的 bean。這是由於它包含 @Primary
註解。當咱們想要指定默認狀況下應該注入特定類型的 bean 時,此註解頗有用。 若是咱們在某個注入點須要另外一個 bean,咱們須要專門指出它。咱們能夠經過 @Qualifier
註解來作到這一點。例如,咱們能夠經過使用 @Qualifier
註釋來指定咱們想要使用 tomEmployee
方法返回的 bean 。 值得注意的是,若是 @Qualifier
和 @Primary
註釋都存在,那麼 @Qualifier
註釋將具備優先權。基本上,@Primary
是定義了默認值,而 @Qualifier
則很是具體。 固然@Component
也可使用@Primary
註解,此次使用的仍是上面3的示例:blog
@Component
@Primary
public class FooFormatter implements Formatter {
public String format() {
return "foo";
}
}
@Component
public class BarFormatter implements Formatter {
public String format() {
return "bar";
}
}
複製代碼
在這種狀況下,@Primary
註解指定了默認注入的是 FooFormatter
,消除了場景中的注入歧義。隊列
在使用 @Autowired
進行自動裝配時,若是 Spring 沒有其餘提示,將會按照須要注入的變量名稱來尋找合適的 bean。也能夠解決依賴注入歧義的問題。讓咱們看一些基於咱們最初的例子的代碼:開發
@Component
public class FooService {
@Autowired
private Formatter fooFormatter;
//todo
}
複製代碼
在這種狀況下,Spring 將肯定要注入的 bean 是 FooFormatter
,由於字段名稱與咱們在該 bean 的 @Component
或者 @Bean
註解中使用的值(默認 @Bean
使用方法名)相匹配。get
經過對 @Qualifier
的探討,咱們知道該註解是用來消除依賴注入衝突的。這種在平常開發,好比 Rabbtimq 的隊列聲明中很常見。小胖哥也經過該註解和其餘上述註解的組合使用和對比中展現了一些經常使用的用法。這將有助於你對 Spring 的依賴注入機制的瞭解。
關注公衆號:Felordcn獲取更多資訊