知識庫 / Spring RSS 訂閱

Spring @Qualifier 註解

Spring
HongKong
10
01:19 PM · Dec 06 ,2025

1. 概述

在本教程中,我們將探討@Qualifier 註解可以幫助我們解決什麼問題,以及如何使用它。

我們還將解釋它與 @Primary 註解以及通過名稱自動裝配的區別。

2. 自動注入需要消除歧義

<em>@Autowired</em> 註解是一種顯式地在 Spring 中指定依賴注入需求的有效方法。雖然它很有用,但也有一些用例,單獨使用此註解不足以讓 Spring 瞭解應該注入哪個 Bean。

默認情況下,Spring 通過類型來解析自動注入的條目。

如果容器中存在多個同類型的 Bean,框架將拋出 <em>NoUniqueBeanDefinitionException</em>,指示有多個 Bean 可供自動注入。

讓我們設想一個場景,其中存在兩個可能的候選 Bean 作為給定實例的 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;
}

如果嘗試將 FooService 加載到我們的上下文中,Spring 框架將會拋出 NoUniqueBeanDefinitionException 異常。這是因為 Spring 不知道應該注入哪個 Bean。為了避免這個問題,有幾種解決方案,其中 @Qualifier 註解就是其中之一。

3. <em @Qualifier</em>> 註解

通過使用 <em @Qualifier</em>> 註解,我們可以消除注入哪個 Bean 的問題

讓我們回顧一下我們之前的例子,看看如何通過包含 <em @Qualifier</em>> 註解來指示我們想要使用的 Bean:

public class FooService {
     
    @Autowired
    @Qualifier("fooFormatter")
    private Formatter formatter;
}

通過包含 @Qualifier 註解,以及我們希望使用的特定實現名稱(例如 Foo),在這個例子中,我們可以避免 Spring 在查找相同類型的多個 Bean 時產生歧義。

需要注意的是,用於使用的 qualifier 的名稱應與 @Component 註解中聲明的名稱相同。

此外,我們也可以在 Formatter 接口實現類上使用 @Qualifier 註解,而不是在它們的 @Component 註解中指定名稱,從而達到相同的效果:

@Component
@Qualifier("fooFormatter")
public class FooFormatter implements Formatter {
    //...
}

@Component
@Qualifier("barFormatter")
public class BarFormatter implements Formatter {
    //...
}

4. @Qualifier@Primary

還有另一個註解叫做 @Primary,我們可以使用它來決定在存在依賴注入歧義時應該注入哪個 Bean。

這個註解 定義了在存在多個相同類型的 Bean 時,偏好。 帶有 @Primary 註解的 Bean 將在未另有指示的情況下被使用。

讓我們來看一個例子:

@Configuration
public class Config {
 
    @Bean
    public Employee johnEmployee() {
        return new Employee("John");
    }
 
    @Bean
    @Primary
    public Employee tonyEmployee() {
        return new Employee("Tony");
    }
}

在本示例中,這兩個方法都返回相同類型的 Employee。 Spring 將注入的 Bean 是由方法 tonyEmployee 返回的那個。 這是因為它包含了 @Primary 註解。 這個註解在我們需要指定某個類型的 Bean 應該默認被注入時非常有用。

如果我們在某個注入點需要使用其他的 Bean,則需要通過 @Qualifier 註解明確指定。 例如,我們可以通過使用 @Qualifier 註解來指定我們想要使用由 johnEmployee 方法返回的 Bean。

值得注意的是,如果同時使用了 @Qualifier @Primary 註解,則 @Qualifier 註解將具有優先權。 基本上,@Primary 定義了一個默認值,而 @Qualifier 則非常具體。

讓我們再看一個使用 @Primary 註解的方法,這次使用之前的示例:

@Component
@Primary
public class FooFormatter implements Formatter {
    //...
}

@Component
public class BarFormatter implements Formatter {
    //...
}

在這種情況下,@Primary 註解放置在其中一個實現類中,將消除歧義。

5. @Qualifier 與通過名稱進行自動注入

當使用自動注入時,另一種選擇是使用字段名稱來注入。 這在沒有其他提示的情況下是默認設置。 讓我們基於我們之前的示例來看一些代碼:

public class FooService {
     
    @Autowired
    private Formatter fooFormatter;
}

在這種情況下,Spring 會確定要注入的 Bean 是 FooFormatter,因為字段名與我們在 @Component 註解中為該 Bean 指定的值匹配。

6. 結論

在本文中,我們描述了需要消除歧義以確定要注入哪些 Bean 的場景。特別是,我們研究了 <em @Qualifier </em> 註解,並將其與確定需要使用的其他類似方法進行了比較。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.