為什么要使用構造方法進行依賴注入


一、前言

我們在使用Spring框架進行開發時,不可避免的要進行依賴注入(Dependency Injection),也就是把實例從Spring容器中取出來進行使用。Spring的依賴注入方式主要有三種,分別為Constructor、Setter和Field。有了選擇的余地,令人糾結的地方就來了,這三種方式哪個更好一些呢?

二、注入方式對比

接下來我們逐一看下這三種注入方式:

Field注入

@Autowired
private DependencyA dependencyA;

優點

  • 注入簡單,只需在字段上添加@Autowired或@Resource;
  • 減少大量冗余代碼,美觀;
  • 新增Field時不需要過多代碼修改;

缺點

  • 很難測試,因為沒有帶參構造和set方法,難以在容器以外使用。
  • 依賴不能是final的
  • 容易出現循環依賴

Setter注入

private DependencyB dependencyB;
@Autowired
public void setDependencyB(DependencyB dependencyB) {
    this.dependencyB = dependencyB;
}

優點

  • 對循環依賴免疫

  • 在對象的整個生命周期內,可以隨時動態的改變依賴。

缺點

  • 依賴不能是final的

Constructor注入

private DependencyC dependencyC;
@Autowired
public DI(DependencyC dependencyC) {
    this.dependencyC = dependencyC;
}

優點

  • 依賴可以是final的
  • 高耦合類隨着構造參數的增長很容易被識別出來
  • 不需要依賴@Autowired注解(當類中只有一個構造方法時,可以省略@Autowired)

缺點

  • 代碼顯得十分臃腫

三、選擇哪種注入方式

Spring官方目前推薦的是構造器注入。根據官方的說法,因為它使人們能夠將應用程序組件實現為不可變對象,並確保所需的依賴項不為null。此外,注入構造函數的組件總是以完全初始化的狀態返回到客戶端(調用)代碼。

  • 不可變對象:說的是可以是字段用final關鍵字修飾。
  • 依賴不為null:因為有了自定義的構造函數,所以程序不再提供默認的空參構造,類在實例化時必須傳入所有需要的參數。
  • 完全初始化的狀態:構造方法的作用就是初始化成員變量,在Java類加載實例化的過程中,構造方法是最后一步,所以返回來的組件都是初始化之后的狀態。

四、總結

三種方式各有利弊,從靠譜程度來說,還是構造器注入更好一些,它能有效避免一些比如循環依賴、空指針等異常的發生。另外,Spring中Bean默認為單例的,有可能會出現線程安全問題,這個時候final就更有必要了。當然,其他兩種方式也有其自己的發光點,我們可以按實際需要選擇使用,或混合使用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM