首頁  >  文章  >  Java  >  大公司為什麼禁止在 Spring Boot 專案中使用 @Autowired 註解?

大公司為什麼禁止在 Spring Boot 專案中使用 @Autowired 註解?

Java后端技术全栈
Java后端技术全栈轉載
2023-08-15 16:00:38988瀏覽

1、說明


#最近公司升級框架,由原來的 <span style="outline: 0px;font-size: 16px;visibility: visible;">spring framerwork 3.0</span>升級到<span style="outline: 0px;font-size: 16px;visibility: visible;">#5.0</span>##,然後寫程式碼的時候突然發現idea在屬性注入的 @Autowired 註解上給出警告提示,就像下面這樣的,也挺懵逼的,畢竟這麼寫也很多年了。

Field injection is not recommended

大公司為什麼禁止在 Spring Boot 專案中使用 @Autowired 註解?

查閱了相關文件了解了一下,原來這個提示是<span style="outline: 0px;font-size: 16px;visibility: visible;">spring framerwork 4.0</span>以後開始出現的,spring 4.0開始就不推薦使用屬性注入,改為推薦構造器注入和setter注入。

下面將展示了spring框架可以使用的不同類型的依賴注入,以及每種依賴注入的適用情況。


2、依賴注入的類型

##儘管針對 spring framerwork 5.1.3<span style="outline: 0px;font-size: 16px;"></span>的文件只定義了兩個主要的依賴注入類型,但實際上有三種;#

  • 基於建構函式的依賴注入
  • #基於setter的依賴注入
  • #基於字段的依賴注入

#其中<span style="outline: 0px;font-size: 16px;">基於字段的依賴注入</span>

大公司為什麼禁止在 Spring Boot 專案中使用 @Autowired 註解?

#被廣泛使用,但是idea或其他靜態程式碼分析工具會給予提示訊息,不建議使用。 ############甚至可以在一些Spring官方指南中看到這種注入方法:####################### #2.1 基於建構子的依賴注入###############在基於建構子的依賴注入中,類別建構子被標註為@Autowired,並包含了許多與要注入的對象相關的參數。 ######
@Component
public class ConstructorBasedInjection {

    private final InjectedBean injectedBean;

    @Autowired
    public ConstructorBasedInjection(InjectedBean injectedBean) {
        this.injectedBean = injectedBean;
    }
}
######然後在spring官方文件中,@Autowired 註解也是可以省去的。 ######
public class SimpleMovieLister {

    // the SimpleMovieLister has a dependency on a MovieFinder
    private MovieFinder movieFinder;

    // a constructor so that the Spring container can inject a MovieFinder
    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // business logic that actually uses the injected MovieFinder is omitted...
}

基于构造函数注入的主要优点是可以将需要注入的字段声明为final, 使得它们会在类实例化期间被初始化,这对于所需的依赖项很方便。

2.2 基于Setter的依赖注入

在基于setter的依赖注入中,setter方法被标注为 @Autowired。一旦使用无参数构造函数或无参数静态工厂方法实例化Bean,为了注入Bean的依赖项,Spring容器将调用这些setter方法。

@Component
public class SetterBasedInjection {

    private InjectedBean injectedBean;

    @Autowired
    public void setInjectedBean(InjectedBean injectedBean) {
        this.injectedBean = injectedBean;
    }
}

和基于构造器的依赖注入一样,在官方文档中,基于Setter的依赖注入中的 @Autowired也可以省去。

public class SimpleMovieLister {

    // the SimpleMovieLister has a dependency on the MovieFinder
    private MovieFinder movieFinder;

    // a setter method so that the Spring container can inject a MovieFinder
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // business logic that actually uses the injected MovieFinder is omitted...
}

2.3 基于属性的依赖注入

在基于属性的依赖注入中,字段/属性被标注为 @Autowired。一旦类被实例化,Spring容器将设置这些字段。

@Component
public class FieldBasedInjection {
    @Autowired
    private InjectedBean injectedBean;
}

正如所看到的,这是依赖注入最干净的方法,因为它避免了添加样板代码,并且不需要声明类的构造函数。代码看起来很干净简洁,但是正如代码检查器已经向我们暗示的那样,这种方法有一些缺点。


3、基於欄位的依賴注入缺陷

3.1 不允許宣告不可變域

基於欄位的依賴注入在宣告為final/immutable的欄位上不起作用,因為這些欄位必須在類別實例化時實例化。聲明不可變依賴項的惟一方法是使用基於建構器的依賴注入。

3.2 容易違反單一職責設計原則

在物件導向的程式設計中,五大設計原則SOLID被廣泛應用,(國內一般為六大設計原則),用以提高程式碼的重用性,可讀性,可靠性和可維護性

##S在SOLID中代表單一職責原則,即一個類別應該只負責一項職責,這個類別提供的所有服務都應該只為它負責的職責服務。

使用基於字段的依賴注入,高頻使用的類別隨著時間的推移,我們會在類別中逐漸添加越來越多的依賴項,我們用著很爽,很容易忽略類別中的依賴已經太多了。但是如果使用基於建構函數的依賴注入,隨著越來越多的依賴項被添加到類別中,構造函數會變得越來越大,我們一眼就可以察覺到哪裡不對勁。

有一個有超過10個參數的建構函數是一個明顯的訊號,表示類別已經轉變一個大而全的函數集合,需要將類別分割成更小、更容易維護的塊。

因此,儘管屬性注入並不是破壞單一責任原則的直接原因,但它隱藏了訊號,使我們很容易忽略這些訊號。

3.3 與依賴注入容器緊密耦合

#使用基於欄位的依賴注入的主要原因是為了避免getter和setter的樣板程式碼或為類別建立建構函式。最後,這意味著設定這些欄位的唯一方法是透過Spring容器實例化類別並使用反射注入它們,否則欄位將保持null。

依賴注入設計模式將類別依賴項的建立與類別本身分開來,並將此責任轉移到類別注入容器,從而允許程式設計解耦,並遵循單一職責和依賴項倒置原則(同樣可靠)。因此,透過自動組裝(autowiring)欄位來實現的類別的解耦,最終會因為再次與類別注入容器(在本例中是Spring)耦合而丟失,從而使類別在Spring容器之外變得無用。

這意味著,如果您想在應用程式容器之外使用您的類,例如用於單元測試,您將被迫使用Spring容器來實例化您的類,因為沒有其他可能的方法(除了反射)來設定自動裝配欄位。

3.4 隱藏依賴關係

#在使用依賴注入時,受影響的類別應該使用公共介面清楚地公開這些依賴項,方法是在建構函數中公開所需的依賴項,或使用方法(setter)公開可選的依賴項。當使用基於字段的依賴注入時,實質上是將這些依賴對外隱藏了。


4、總結

我們已經看到,基於字段的注入應該盡可能地避免,因為它有許多缺點,無論它看起來多麼優雅。建議的方法是使用基於建構函式和基於setter的依賴注入。

對於必要的依賴,建議使用基於建構函式的注入,設定它們為不可變的,並防止它們為null。對於可選的依賴項,建議使用基於setter的注入。

以上是大公司為什麼禁止在 Spring Boot 專案中使用 @Autowired 註解?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:Java后端技术全栈。如有侵權,請聯絡admin@php.cn刪除