你知道Spring中為何不建議使用字段注入嗎
在使用Idea中通過(guò)注解注入字段時(shí)是否遇見(jiàn)過(guò)這樣一個(gè)提示:
Field injection is not recommended(不推薦使用字段注入)
一. 什么是字段注入,Spring中依賴(lài)注入的方式有哪些?
在Spring中依賴(lài)注入有三大類(lèi):字段注入、構(gòu)造器注入、Setter方法注入。
字段注入是將Bean作為字段注入到類(lèi)中,也是最方便,用的最多的注入方式。
二. 官方為什么不推薦使用字段注入
首先來(lái)看字段注入
@RestController public class TestHandleController { @Autowired TestHandleService testHandleService; public void helloTestService(){ testHandleService.hello(); } }
字段注入的非常的簡(jiǎn)便,通過(guò)以上代碼我們就可以輕松的使用TestHandleService類(lèi),但是如果變成下面這樣呢:
TestHandleController testHandle = new TestHandleController(); testHandle.helloTestService();
這樣執(zhí)行結(jié)果為空指針異常,這就是字段注入的第一個(gè)問(wèn)題:對(duì)象的外部可見(jiàn)性,無(wú)法在容器外部實(shí)例化TestHandleService,類(lèi)和容器的耦合度過(guò)高,無(wú)法脫離容器訪問(wèn)目標(biāo)對(duì)象。
接下來(lái)看第二段代碼:
public class TestA(){ @Autowired private TestB testB; } public class TestB(){ @Autowired private TestA testA; }
這段代碼在idea中不會(huì)報(bào)任何錯(cuò)誤,但是當(dāng)你啟動(dòng)項(xiàng)目時(shí)會(huì)發(fā)現(xiàn)報(bào)錯(cuò),大致意思是:創(chuàng)建Bean失敗,原因是當(dāng)前Bean已經(jīng)作為循環(huán)引用的一部分注入到了其他Bean中。
這就是字段注入的第二個(gè)問(wèn)題:可能導(dǎo)致循環(huán)依賴(lài)
字段注入還有第三個(gè)問(wèn)題:無(wú)法設(shè)置注入的對(duì)象為final,也無(wú)法注入靜態(tài)變量,原因是變量必須在類(lèi)實(shí)例化進(jìn)行初始化。
整理一下,字段注入可能引起的三個(gè)問(wèn)題:
1. 對(duì)象的外部可見(jiàn)性
2. 可能導(dǎo)致循環(huán)依賴(lài)
3. 無(wú)法設(shè)置注入的對(duì)象為final,也無(wú)法注入靜態(tài)變量
接下來(lái)看構(gòu)造器注入--官方推薦的注入方式
使用形式也很簡(jiǎn)單:
private TestHandleService testHandleService; @Autowired public TestHandleController(TestHandleService testHandleService){ this.testHandleService = testHandleService; }
通過(guò)構(gòu)造器的方式將Bean注入到字段中。
構(gòu)造器注入能夠保證注入的組件不可變,并且確保需要的依賴(lài)不為空。
這樣就可以將變量設(shè)置為final,并且傳遞的肯定是一個(gè)對(duì)象,避免出現(xiàn)空指針異常。
若是出現(xiàn)字段注入中循環(huán)依賴(lài)的問(wèn)題,在項(xiàng)目啟動(dòng)時(shí)Spring會(huì)非常形象的將錯(cuò)誤拋出來(lái):
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]
└─────┘
顯而易見(jiàn)的發(fā)現(xiàn)錯(cuò)誤的地方。
由此可見(jiàn),字段注入的三大問(wèn)題都能解決,但是構(gòu)造器注入就沒(méi)有其他問(wèn)題了嗎?
答案肯定是否定的,當(dāng)依賴(lài)的對(duì)象很多時(shí),需要嚴(yán)格按照構(gòu)造器的順序去填寫(xiě)依賴(lài)的對(duì)象,這將導(dǎo)致代碼可讀性和可維護(hù)性變得很差。
這時(shí)候可以引入Setter方法進(jìn)行注入,Setter方法和構(gòu)造器注入很像,不過(guò)Setter更具有可讀性。
并且使用Setter方法注入可以實(shí)現(xiàn)按需注入,不使用的對(duì)象不需要想構(gòu)造器注入一樣強(qiáng)制注入。
總結(jié)一下三種注入方式:
構(gòu)造器注入適用于強(qiáng)制對(duì)象注入
Setter注入適合可選對(duì)象注入
字段注入方式應(yīng)該盡量避免,因?yàn)閷?duì)象無(wú)法脫離容器獨(dú)立運(yùn)行(話(huà)雖這么說(shuō),但我還是字段注入用得多,因?yàn)榉奖惆?[/狗頭])
總結(jié)
到此這篇關(guān)于為何不建議使用字段注入的文章就介紹到這了,更多相關(guān)Spring不建議使用字段注入內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Jboss Marshalling服務(wù)端無(wú)法接受消息
這篇文章主要介紹了Jboss Marshalling服務(wù)端無(wú)法接受消息,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03jboss( WildFly)上運(yùn)行 springboot程序的步驟詳解
這篇文章主要介紹了jboss( WildFly)上運(yùn)行 springboot程序的步驟詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02解決SpringBoot框架因post數(shù)據(jù)量過(guò)大沒(méi)反應(yīng)問(wèn)題(踩坑)
這篇文章主要介紹了解決SpringBoot框架因post數(shù)據(jù)量過(guò)大沒(méi)反應(yīng)問(wèn)題(踩坑),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09簡(jiǎn)單了解Thymeleaf語(yǔ)法 數(shù)據(jù)延遲加載使用實(shí)例
這篇文章主要介紹了簡(jiǎn)單了解Thymeleaf語(yǔ)法 數(shù)據(jù)延遲加載使用實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2010-05-05