切換語言為:簡體

一文講明白@Resource和@Autowired區別

  • 爱糖宝
  • 2024-08-21
  • 2062
  • 0
  • 0

在Spring框架中,依賴注入(Dependency Injection,DI)是核心功能之一,透過它可以輕鬆管理物件的生命週期及其依賴關係。在實際開發中,@Resource@Autowired是常見的依賴注入註解,但它們的功能、使用場景以及推薦使用的方式存在一定的差異。本文將詳細解釋這兩者的區別,並探討為何近年來@Autowired不再被推薦使用。

1. @Resource@Autowired的基本概念

1.1 @Resource

@Resource是由JSR-250規範定義的註解,是Java EE標準的一部分。它可以用於欄位、方法和類,並透過名稱或型別進行依賴注入。@Resource註解通常使用在應用中需要與JNDI、EJB等Java EE服務整合的場景下。

  • 按名稱注入:預設情況下,@Resource會根據欄位或方法的名稱進行注入。Spring會首先嚐試在上下文中查詢與欄位名稱匹配的Bean,如果找到則注入該Bean。

  • 按型別注入:如果按名稱無法找到匹配的Bean,@Resource將嘗試按型別查詢與欄位型別匹配的Bean。

@Resource
private MyService myService;

1.2 @Autowired

@Autowired是Spring框架提供的註解,專門用於依賴注入。與@Resource不同,@Autowired預設是按型別進行注入的。如果在上下文中有多個同類型的Bean,Spring會使用@Qualifier註解來進一步指定注入的Bean。

  • 按型別注入@Autowired註解會根據欄位或方法引數的型別在上下文中查詢匹配的Bean,並進行注入。

  • 強制依賴:預設情況下,@Autowired是必需的,即如果找不到匹配的Bean,Spring將丟擲異常。可以透過設定required=false來使其成為可選依賴。

@Autowired 
private MyService myService;

2. @Resource@Autowired的詳細區別

2.1 註解來源與相容性
  • @Resource:屬於Java標準的一部分(JSR-250),與Spring無關,因此在Java EE和Spring應用中都可以使用。由於它是Java原生註解,因此與其他Java EE技術棧(如EJB、JPA)有良好的相容性。

  • @Autowired:特定於Spring框架,無法在非Spring環境中使用。它是Spring框架提供的核心功能之一,主要用於Spring應用中的依賴注入。

2.2 注入方式
  • @Resource:預設按名稱注入,若找不到則按型別注入。可以透過name屬性顯式指定要注入的Bean名稱。

  • @Autowired:預設按型別注入,若有多個同類型的Bean時,需要結合@Qualifier@Primary註解來明確指定注入的Bean。

2.3 使用場景
  • @Resource:通常用於需要與Java EE其他技術整合的場景,或在不依賴Spring框架的環境中使用。

  • @Autowired:主要用於Spring應用中,特別是當應用高度依賴Spring的DI功能時。

2.4 可配置性
  • @Resource:透過name屬性可以顯式指定Bean的名稱,從而提供更精確的控制。

  • @Autowired:無法透過註解直接指定Bean名稱,而是依賴於型別匹配。需要結合@Qualifier來指定特定的Bean。

3. 為什麼不再推薦使用@Autowired

隨著Spring的不斷演進,@Autowired的使用逐漸被更現代的方式所替代,原因主要有以下幾點:

3.1 @Autowired的隱式依賴

@Autowired預設按型別注入,容易導致程式碼對Spring容器的隱式依賴性增強,從而降低了程式碼的可測試性和靈活性。在單元測試中,如果不啟動Spring上下文,@Autowired註解無法正常工作,導致測試複雜性增加。

3.2 推薦使用建構函式注入

Spring團隊和許多開發者現在更推薦使用建構函式注入,而非欄位注入。建構函式注入更符合依賴注入的原則,可以確保Bean的完整性,避免迴圈依賴問題。同時,建構函式注入的程式碼更容易測試,因為可以直接在建構函式中傳遞Mock物件。

public class MyService {
    private final MyRepository myRepository;

    @Autowired
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
}

3.3 @Autowired註解濫用

由於@Autowired的便捷性,容易導致開發者濫用它,隨意地在任何類中注入依賴,結果導致程式碼結構混亂,職責不清。過度依賴@Autowired可能使得程式碼維護和重構變得更加困難。

3.4 Spring Boot和@ConfigurationProperties

在Spring Boot中,@ConfigurationProperties註解被廣泛使用,它能夠更加優雅地繫結外部配置到Bean中,並且推薦使用建構函式注入方式。這樣不僅增強了配置的靈活性,還提升了程式碼的可讀性和維護性。

@ConfigurationProperties(prefix = "app.config")
public class AppConfig {
    private String url;
    private int timeout;

    public AppConfig(String url, int timeout) {
        this.url = url;
        this.timeout = timeout;
    }

    // getter and setter
}

4. 結論

@Resource@Autowired在Spring框架中都是用於實現依賴注入的註解,但它們的使用場景、功能和推薦程度各有不同。@Resource適用於需要與Java EE技術整合的場景,而@Autowired主要在Spring應用中使用。隨著Spring框架的發展,@Autowired逐漸不再被推薦,取而代之的是建構函式注入等更加現代和靈活的依賴注入方式。

在現代的Spring開發中,使用建構函式注入不僅能夠提高程式碼的可測試性和靈活性,還能避免許多潛在的問題。因此,在新專案或現有專案中逐步減少@Autowired的使用,是一個值得考慮的方向。

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.