idea為何推薦@Resource而不是@Autowired註解

2024年2月6日 21点热度 0人点赞

當我們使用IntelliJ IDEA進行Java開發時,你可能曾經註意到一個小提示,該提示在你給字段添加@Autowired註解時出現,提示內容是:"Field injection is not recommended",翻譯過來就是"字段註入不建議"。這個警告可能讓你有些困惑,特別是當你知道還有另一個註解@Resource,它可以用於字段註入,但沒有類似的警告。為什麼IDEA不推薦使用@Autowired註解?這個問題值得深入探討。

在本文中,我將詳細討論@Autowired和@Resource註解,以及為什麼IDEA會給出這個警告。我還會介紹Spring中的依賴註入方式,以及如何正確選擇和使用這些註解。最後,我將探討為什麼一些開發者更傾向於使用@Resource而不是@Autowired,以及這兩者之間的區別。

為什麼要使用依賴註入?

在我們深入討論@Autowired和@Resource之前,讓我們先理解為什麼需要依賴註入(Dependency Injection,簡稱DI)以及DI的好處。

在軟件開發中,我們經常會創建各種對象(也稱為組件),這些對象可能會依賴於其他對象才能正常工作。依賴註入是一種將這些依賴關系解耦的方法,它有助於提高代碼的可維護性、可測試性和可擴展性。通過將依賴關系註入到組件中,而不是在組件內部硬編碼它們,我們可以更容易地更改依賴關系,以適應不同的情況。

Spring框架是一個廣泛使用依賴註入的Java框架,它提供了多種方式來實現依賴註入,包括構造器註入、Setter註入和字段註入。接下來,讓我們分別了解這些方式。

Spring中的依賴註入方式

構造器註入

構造器註入是將依賴關系通過組件的構造方法傳遞的方式。這種方式強調了組件的不變性(Immutable)和強依賴,因為一旦組件被創建,它的依賴關系就不可改變。

以下是一個示例,演示了如何使用構造器註入:

public class UserService {
    private final UserRepository userRepository;
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    // ...
}

在上面的代碼中,UserService的依賴關系(UserRepository)通過構造器註入。

構造器註入的優點包括:

  • 明確的依賴關系:構造器參數清晰地指出了組件的依賴。
  • 不變性:一旦依賴被設置,它就不能再被修改。

Setter註入

Setter註入是通過Setter方法設置依賴關系的方式。與構造器註入不同,Setter註入允許依賴關系在組件創建後進行更改。

以下是一個示例,演示了如何使用Setter註入:

public class UserService {
    private UserRepository userRepository;
    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    // ...
}

Setter註入的優點包括:

  • 可變性:允許在組件創建後更改依賴關系。
  • 可選性:某些依賴可以是可選的,不設置依賴也可以正常運行。

字段註入

字段註入是將依賴關系直接註入到字段上的方式,通常使用@Autowired或@Resource註解來實現。

以下是一個示例,演示了如何使用@Autowired進行字段註入:

public class UserService {
    @Autowired
    private UserRepository userRepository;
    // ...
}

字段註入的優點包括:

  • 簡潔性:減少了冗餘的Setter方法或構造器參數。
  • 可選性:字段可以是可選的,如果依賴未註入,字段將保持null。

為什麼IDEA不推薦使用@Autowired註解?

現在,讓我們回到問題的核心:為什麼IDEA不推薦使用@Autowired註解?要理解這一點,我們需要考慮@Autowired和@Resource之間的差異以及它們在不同的情況下的使用建議。

@Autowired與@Resource的區別

  • 依賴識別方式

:@Autowired默認按照類型進行查找依賴,如果需要按名稱查找,可以搭配@Qualifier註解。而@Resource默認按名稱查找依賴,如果找不到名稱匹配的依賴,它會嘗試按照類型查找。

  • 適用對象

:@Autowired可以用於構造器、方法、方法參數和字段的註入,而@Resource隻能用於方法和字段的註入。

  • 提供方

:@Autowired是Spring框架提供的註解,而@Resource是Java標準(JSR-250)提供的註解。

Spring官方的建議

根據Spring官方的建議,推薦使用構造器註入和Setter註入,而盡量避免使用字段註入。字段註入被認為是一種不太理想的方式,因為它具有以下缺點:

  • 不利於不變性

:與構造器註入不同,字段註入無法將不變的依賴關系傳遞給組件,因為字段可以在任何時候更改。

  • 可見性問題

:外部無法明確看到組件所依賴的內容,因為依

賴關系被隱藏在組件內部。這可能導致代碼可讀性下降。

  • 緊密綁定

:字段註入會導致組件與IoC容器緊密綁定,使組件在沒有容器的情況下難以使用,也使單元測試更加復雜。

  • 不明顯的依賴關系

:當依賴關系變得復雜時,使用字段註入可能導致依賴關系不夠明顯,難以理解組件的需求。

為什麼IDEA給出警告?

回到最初的問題,為什麼IDEA會給出關於@Autowired的警告,而不是@Resource呢?

我們可以理解這個警告是為了提醒開發者@Autowired是Spring特定的註解,與Spring框架緊密相關。如果以後決定更換不同的IoC容器,那麼@Autowired可能不再適用,因為其他容器可能不支持它。這種警告有助於開發者在選擇依賴註入方式時考慮到可移植性和框架切換的可能性。

而@Resource是Java標準(JSR-250)提供的註解,幾乎所有的IoC容器都會支持它。因此,即使你將來更換了容器,使用@Resource的代碼仍然可以正常工作,不需要類似的警告。

為什麼一些開發者更傾向於使用@Resource?

在某些情況下,開發者更傾向於使用@Resource而不是@Autowired。這可能是因為@Resource具有更廣泛的兼容性,適用於不同的IoC容器。此外,一些開發者認為@Resource更符合Java的標準化,從而提高了代碼的可移植性。

然而,需要註意的是,根據具體的使用場景和團隊約定,選擇@Autowired或@Resource可能會有所不同。最重要的是,開發者應該明確了解它們之間的差異,並根據項目的需要進行選擇。

結論

在IDEA中看到警告"Field injection is not recommended"時,現在你應該明白了為什麼會出現這個警告。它是為了提醒開發者在依賴註入時要謹慎選擇註解,避免過度使用字段註入,以免導致代碼可維護性下降和與特定框架的緊密綁定。

總之,選擇依賴註入方式和註解時,需要權衡各種因素,包括項目需求、可維護性、可測試性以及可能的框架更換。遵循Spring官方的建議,盡量避免過度使用字段註入,可以提高代碼的靈活性和可移植性。最終,選擇@Autowired或@Resource應該取決於項目的具體情況和團隊的約定。

原文:
https://juejin.cn/post/7280007606236086326

作者:啵啵腸

#記錄我的2024#