Spring中為什么不建議使用字段注入


在使用Idea中通過注解注入字段時是否遇見過這樣一個提示:

Field injection is not recommended(不推薦使用字段注入)

一. 什么是字段注入,Spring中依賴注入的方式有哪些?

在Spring中依賴注入有三大類:字段注入、構造器注入、Setter方法注入。

字段注入是將Bean作為字段注入到類中,也是最方便,用的最多的注入方式。

 

二. 官方為什么不推薦使用字段注入

 首先來看字段注入

@RestController
public class TestHandleController {

@Autowired
TestHandleService testHandleService;

public void helloTestService(){
testHandleService.hello();
}
}

字段注入的非常的簡便,通過以上代碼我們就可以輕松的使用TestHandleService類,但是如果變成下面這樣呢:

TestHandleController testHandle = new TestHandleController();
testHandle.helloTestService();

這樣執行結果為空指針異常,這就是字段注入的第一個問題:對象的外部可見性,無法在容器外部實例化TestHandleService(例如在測試類中無法注入該組件),類和容器的耦合度過高,無法脫離容器訪問目標對象。

接下來看第二段代碼:

public class TestA(){

@Autowired
private TestB testB;

}

public class TestB(){

@Autowired
private TestA testA;

}

這段代碼在idea中不會報任何錯誤,但是當你啟動項目時會發現報錯,大致意思是:創建Bean失敗,原因是當前Bean已經作為循環引用的一部分注入到了其他Bean中。

這就是字段注入的第二個問題:可能導致循環依賴

字段注入還有第三個問題:無法設置注入的對象為final,也無法注入靜態變量,原因是變量必須在類實例化進行初始化。

整理一下,字段注入可能引起的三個問題:

1. 對象的外部可見性

2. 可能導致循環依賴

3. 無法設置注入的對象為final,也無法注入靜態變量


 接下來看構造器注入--官方推薦的注入方式

使用形式也很簡單:

private TestHandleService testHandleService;

@Autowired
public TestHandleController(TestHandleService testHandleService){
this.testHandleService = testHandleService;
}

通過構造器的方式將Bean注入到字段中。

構造器注入能夠保證注入的組件不可變,並且確保需要的依賴不為空。

這樣就可以將變量設置為final,並且傳遞的肯定是一個對象,避免出現空指針異常。

若是出現字段注入中循環依賴的問題,在項目啟動時Spring會非常形象的將錯誤拋出來:

Description:

The dependencies of some of the beans in the application context form a cycle:

testContrtoller (field private com.example.designstudy.service.TestService com.example.designstudy.controller.TestContrtoller.testService)
┌─────┐
| testService defined in file [D:\design-study\target\classes\com\example\designstudy\service\TestService.class]
↑ ↓
| testHandleServiceImpl defined in file [D:\design-study\target\classes\com\example\designstudy\service\impl\TestHandleServiceImpl.class]
└─────┘

顯而易見的發現錯誤的地方。

由此可見,字段注入的三大問題都能解決,但是構造器注入就沒有其他問題了嗎?

答案肯定是否定的,當依賴的對象很多時,需要嚴格按照構造器的順序去填寫依賴的對象,這將導致代碼可讀性和可維護性變得很差。

這時候可以引入Setter方法進行注入,Setter方法和構造器注入很像,不過Setter更具有可讀性。

並且使用Setter方法注入可以實現按需注入,不使用的對象不需要想構造器注入一樣強制注入。

總結一下三種注入方式:

構造器注入適用於強制對象注入 

Setter注入適合可選對象注入

字段注入方式應該盡量避免,因為對象無法脫離容器獨立運行(話雖這么說,但我還是字段注入用得多,因為方便啊 [/狗頭])


免責聲明!

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



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