知識庫 / Spring RSS 訂閱

Spring @Autowired 指導手冊

Spring
HongKong
5
02:50 PM · Dec 06 ,2025

1. 概述

從 Spring 2.5 版本開始,框架引入了基於註解的 依賴注入 (Dependency Injection) 功能。該功能的關鍵註解是 @Autowired它允許 Spring 解決並注入協作的 Bean 到我們的 Bean 中

在本教程中,我們首先將瞭解如何啓用自動裝配以及 各種 自動裝配 Bean 的 方式。之後,我們將討論 使用 @Qualifier 註解解決 Bean 衝突,以及潛在的異常場景。

2. 啓用 @Autowired 註解

Spring 框架實現了自動依賴注入。換句話説,通過在 Spring 配置文件中聲明所有 Bean 的依賴關係,Spring 容器可以自動注入協作 Bean 之間的關係。 這種機制被稱為 Spring Bean 自動注入

為了在我們的應用程序中使用基於 Java 的配置,讓我們啓用註解驅動的注入,以便加載我們的 Spring 配置:

@Configuration
@ComponentScan("com.baeldung.autowire.sample")
public class AppConfig {}

或者,`

此外,。 此單一標註相當於使用 `

讓我們在應用程序的主類中使用此標註:

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

因此,當我們運行這個 Spring Boot 應用程序時,它會自動掃描當前包及其子包中的所有組件 這樣它會將它們註冊到 Spring 的 Application Context 中,並允許我們使用 @Autowired 注入 Bean。

3. 使用 @Autowired

啓用註解注入後,我們可以使用自動裝配功能,應用於屬性、setter 方法和構造函數

3.1. 使用 <em @Autowired 註解處理屬性

讓我們看看如何使用 <em @Autowired 註解來標註屬性。這消除了使用 getter 和 setter 的需求。

首先,讓我們定義一個 <em fooFormatter Bean:

@Component("fooFormatter")
public class FooFormatter {
    public String format() {
        return "foo";
    }
}

然後,我們將使用 FooService 注入該 Bean,在字段定義上使用 @Autowired

@Component
public class FooService {  
    @Autowired
    private FooFormatter fooFormatter;
}

因此,Spring 在創建 fooFormatter 時會注入它。

3.2. 在 Setter 方法上使用 <em @Autowired>

現在,讓我們嘗試在 Setter 方法上添加 <em @Autowired> 註解。

在下面的示例中,當 FooService 被創建時,Setter 方法被調用,並傳入 FooFormatter 的實例:

public class FooService {
    private FooFormatter fooFormatter;
    @Autowired
    public void setFormatter(FooFormatter fooFormatter) {
        this.fooFormatter = fooFormatter;
    }
}

3.3. 在構造函數中使用 <em @Autowired>

最後,讓我們在構造函數中使用 <em @Autowired>。

我們將看到 Spring 將 <em FooFormatter> 作為參數注入到 <em FooService> 的構造函數中。

public class FooService {
    private FooFormatter fooFormatter;
    @Autowired
    public FooService(FooFormatter fooFormatter) {
        this.fooFormatter = fooFormatter;
    }
}

4. @Autowired 和可選依賴項

當一個 Bean 正在被構建時,@Autowired 依賴項應該可用。否則,如果 Spring 無法解析 Bean 用於注入,它將拋出異常

因此,它防止了 Spring 容器由於異常而無法成功啓動:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [com.autowire.sample.FooDAO] found for dependency: 
expected at least 1 bean which qualifies as autowire candidate for this dependency. 
Dependency annotations: 
{@org.springframework.beans.factory.annotation.Autowired(required=true)}

為了解決這個問題,我們需要聲明一個指定類型的Bean:

public class FooService {
    @Autowired(required = false)
    private FooDAO dataAccessor; 
}

5. 自動注入解析

默認情況下,Spring 通過類型解析 @Autowired 聲明。 如果容器中存在同類型的多個 Bean,框架將拋出致命異常

為了解決此衝突,我們需要明確地告訴 Spring 我們想要注入哪個 Bean。

5.1. 通過 @Qualifier 進行自動注入

例如,讓我們看看如何使用 @Qualifier 註解來指定所需的 Bean。

首先,我們將定義 2 個類型為 Formatter 的 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";
    }
}

現在讓我們嘗試將 Formatter Bean 注入到 FooService 類中:

public class FooService {
    @Autowired
    private Formatter formatter;
}

在我們的示例中,Spring 容器中提供了兩個具體的 <em >Formatter</em> 實現。因此,當構建 <em >FooService</em> 時,Spring 會拋出 <em >NoUniqueBeanDefinitionException</em> 異常:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
No qualifying bean of type [com.autowire.sample.Formatter] is defined: 
expected single matching bean but found 2: barFormatter,fooFormatter

我們可以通過縮小實現方式,使用 @Qualifier 註解來避免這種情況:

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

當存在同類型的多個Bean時,建議使用 @Qualifier 以避免歧義。

請注意,@Qualifier 註解的值與我們的 FooFormatter 實現中的 @Component 註解中聲明的名稱相匹配。

5.2. 自定義配額自動注入

Spring 還允許我們創建自己的自定義 <em @Qualifier</em>> 註解。 要做到這一點,我們應該為 <em @Qualifier</em>> 註解提供定義:

@Qualifier
@Target({
  ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface FormatterType {  
    String value();
}

然後,我們可以使用 FormatterType 在各種實現中指定自定義值:

@FormatterType("Foo")
@Component
public class FooFormatter implements Formatter {
    public String format() {
        return "foo";
    }
}
@FormatterType("Bar")
@Component
public class BarFormatter implements Formatter {
    public String format() {
        return "bar";
    }
}

最後,我們的自定義 Qualifier 註解已準備好用於自動裝配:

@Component
public class FooService {  
    @Autowired
    @FormatterType("Foo")
    private Formatter formatter;
}

指定在 @Target 標記元註解中的值會限制標記的適用範圍,在我們的示例中,該範圍包括字段、方法、類型和參數。

5.3. 通過名稱自動注入

Spring 使用 Bean 的名稱作為默認的 qualifier 值。 它會檢查容器,查找與 property 屬性完全相同的 Bean。

因此,在我們的示例中,Spring 將 fooFormatter 屬性名稱與 FooFormatter 實現匹配。 因此,它在構造 FooService 時注入該特定實現。

public class FooService {
 @Autowired 
private Formatter fooFormatter; 
}

6. 結論

在本文中,我們討論了自動裝配及其使用方法。我們還研究瞭如何解決由於缺少 Bean 或歧義 Bean 注入引起的兩種常見自動裝配異常。

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

發佈 評論

Some HTML is okay.