Spring @Qualifier 的使用,以及與 @Primary 的關係

通過本篇,你將學到:@Qualifier 的使用方法, 以及和 @Primary 的關係。

一、概述

Qualifier 英文解釋中,包含合格者、限定者的意思。透過含義,我們也可以大致的判斷出@Qualifier註解,和過濾和篩選有關。

果不其然,@Qualifier 註解就是爲了消除歧義(當Spring無法判斷出哪個bean應該被注入時),限制bean的注入,指定我們需要注入的類。

使用 @Autowired 註解是 Spring 依賴注入的絕好方法,這也是我們在業務中經常使用的註解,但是有些場景下僅僅靠這個註解不足以讓Spring知道到底要注入哪個 bean。如果容器中有多個相同類型的 bean,則框架將拋出異常 - “NoUniqueBeanDefinitionException”, 以提示有多個滿足條件的 bean 進行自動裝配。

程序無法正確做出判斷使用哪一個 bean,下面就是個鮮活的例子:

public interface Formatter {
    String format();
}

@Component("firstFormatter")
public class FirstFormatter implements Formatter {
    @Override
    public String format() {
        return "first";
    }
}

@Component("secondFormatter")
public class SecondFormatter implements Formatter {
    @Override
    public String format() {
        return "second";
    }
}

當我們在 Rest 層注入 Formatter 服務時,由於存在兩個實現類,導致“不唯一bean”的錯誤,IDEA編譯器也會提醒並提示我們解決辦法。

二、@Qualifie

在依賴注入時,因爲@Autowired 註解是by type的,當類型存在相同時,使用@Qualifier 註解可以消除歧義,如下:

@SpringBootTest
class QualifierTest {
    @Qualifier("firstFormatter")
    @Autowired
    private Formatter formatter;
    @Test
    void test() {
        System.out.println(formatter.format());    // 輸出:first
    }
}

@Qualifier 註解的作用,就是指定我們注入的是哪個類,防止拋出“不唯一bean”的異常。

注意:@Qualifier()後面帶的參數名稱,必須爲我們之前定義@Service註解的名稱之一,不能無中生有

三、@Paimary

還有另一個名爲 @Primary 的註解。當存在多個相同類型的 bean 時,此註解定義了首選項,除非另有說明,否則將使用與 @Primary 註釋關聯的 bean 。

public interface Formatter {
    String format();
}

@Primary 
@Component("firstFormatter")
public class FirstFormatter implements Formatter {
    @Override
    public String format() {
        return "first";
    }
}

@Component("secondFormatter")
public class SecondFormatter implements Formatter {
    @Override
    public String format() {
        return "second";
    }
}

值得注意的是:如果 @Qualifier 和 @Primary 註釋都存在,那麼 @Qualifier 註釋將具有優先權。因爲 @Primary 定義的只是默認值,而 @Qualifier 則非常具體的指定了哪一個。

四、其他

除此之外,我們也可以通過名稱來實現自動注入,這與使用 @Qualifier 註解指定類的原理相同,如下:

@SpringBootTest
class QualifierTest {
    @Autowired
    private Formatter firstFormatter;
    @Test
    void test() {
        System.out.println(formatter.format());    // 輸出:first
    }
}

五、總結

  • @Qualifier 註解是用來消除依賴注入衝突的;
  • @Primary 註解可以定義默認注入的類;
  • 該註解在 MQ 的使用中較常見,如:RabbitMQ 的隊列聲明...

少俠請留步 ... ヾ(◍°∇°◍)ノ゙ ... 
歡迎點贊、評論、加關注,讓更多人看到學到賺到
更多精彩,請關注我的"今日頭條號":Java雲筆記

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章