spring?和?idea?建議不要使用?@Autowired注解的原因解析
前言
這是我在這個(gè)網(wǎng)站整理的筆記,有錯(cuò)誤的地方請(qǐng)指出,關(guān)注我,接下來(lái)還會(huì)持續(xù)更新。 作者:神的孩子都在歌唱
一. 問(wèn)題描述
公司項(xiàng)目閑下來(lái)了之后,我就開始整理之前寫過(guò)的代碼,發(fā)現(xiàn)每個(gè)Autowired下面都有警告,**Field injection is not recommended(不建議使用字段注入)**這是什么意思呢?
二. 警告原因和如何去除
百度了一圈,以下是我總結(jié)的問(wèn)題答案
雖然 @Autowired
是 Spring Boot 中最常用的依賴注入方式之一,但是在實(shí)際開發(fā)中,建議盡量避免使用 @Autowired
,而是使用構(gòu)造函數(shù)注入或者 @Resource
注解注入。
以下是使用 @Autowired
存在的一些問(wèn)題:
- 不夠明確:在使用
@Autowired
進(jìn)行依賴注入時(shí),Spring 會(huì)自動(dòng)根據(jù)類型來(lái)匹配 Bean,如果存在多個(gè)類型相同的 Bean,就會(huì)產(chǎn)生歧義。此時(shí),需要使用@Qualifier
注解或者@Primary
注解來(lái)指定具體的 Bean。但是,這種方式不夠明確,容易出現(xiàn)錯(cuò)誤。 - 難以測(cè)試:使用
@Autowired
進(jìn)行依賴注入時(shí),需要在測(cè)試中手動(dòng)創(chuàng)建 Bean,并將其注入到測(cè)試類中。這種方式比較麻煩,而且容易出現(xiàn)錯(cuò)誤。 - 無(wú)法保證依賴注入的順序:在使用
@Autowired
進(jìn)行依賴注入時(shí),Spring 會(huì)根據(jù) Bean 的創(chuàng)建順序來(lái)注入依賴,這種方式無(wú)法保證依賴注入的順序。
因此,在實(shí)際開發(fā)中,建議使用構(gòu)造函數(shù)注入或者 @Resource
注解注入。這種方式更加明確、易于測(cè)試,并且可以保證依賴注入的順序,所以idea不建議使用Autowired
注入了。
例如,使用構(gòu)造函數(shù)注入的方式可以這樣寫:
@Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } // ... }
或者使用 @Resource
注解注入的方式可以這樣寫:
@Service public class UserService { @Resource private UserRepository userRepository; // ... }
這些方式都可以避免使用 @Autowired
帶來(lái)的警告問(wèn)題。
三. 個(gè)人的收獲和解決方案
3. 1 個(gè)人感受
參考了很多個(gè)文章之后,我不在使用autowired,對(duì)我來(lái)說(shuō)使用autowired最大的問(wèn)題是會(huì)寫出很多個(gè)循環(huán)依賴出來(lái),雖然Spring 使用了三級(jí)緩存來(lái)處理循環(huán)依賴,項(xiàng)目也能夠正常運(yùn)行,但是這樣會(huì)導(dǎo)致很多循環(huán)依賴問(wèn)題我們發(fā)現(xiàn)不了,寫出很多不規(guī)范的代碼。每個(gè)模塊之間應(yīng)該是分層的,每個(gè)模塊、類或方法應(yīng)該只負(fù)責(zé)一個(gè)明確的功能或任務(wù),遵循單一職責(zé)。
像以下循環(huán)依賴的報(bào)錯(cuò),使用autowired就能夠解決
以上是我的收獲,不知道有沒(méi)有理解錯(cuò)誤的地方,希望大家指出
3.2 通過(guò)構(gòu)造函數(shù)解決警告問(wèn)題
為了消除警告,避免寫出循環(huán)依賴的代碼,我就使用了構(gòu)造函數(shù)注入,以下是我項(xiàng)目中使用的方式,通過(guò)
@RequiredArgsConstructor
可以減少很多代碼
@RequiredArgsConstructor
是Lombok框架中的注解之一,用于自動(dòng)生成一個(gè)包含所有必需參數(shù)的構(gòu)造函數(shù)。它可以幫助開發(fā)人員減少代碼量,避免手動(dòng)編寫構(gòu)造函數(shù)。使用@RequiredArgsConstructor
注解時(shí),Lombok會(huì)自動(dòng)檢測(cè)類中所有被聲明為final
的字段,并將其作為構(gòu)造函數(shù)的參數(shù)。生成的構(gòu)造函數(shù)將使用這些參數(shù)來(lái)初始化字段。
例如,下面是一個(gè)使用@RequiredArgsConstructor
注解:
@RequiredArgsConstructor public class MyService { private final MyRepository myRepository; private final MyLogger myLogger; // ... }
@RequiredArgsConstructor
注解會(huì)自動(dòng)生成一個(gè)構(gòu)造函數(shù),該構(gòu)造函數(shù)包含兩個(gè)參數(shù):myRepository
和myLogger
。這兩個(gè)參數(shù)都是被聲明為final
的字段,因此它們將被用于初始化相應(yīng)的字段。
生成的構(gòu)造函數(shù)等效于以下代碼:
public class MyService { private final MyRepository myRepository; private final MyLogger myLogger; public MyService(MyRepository myRepository, MyLogger myLogger) { this.myRepository = myRepository; this.myLogger = myLogger; } // ... }
使用@RequiredArgsConstructor
注解可以讓開發(fā)人員更快地編寫代碼,并避免手動(dòng)編寫構(gòu)造函數(shù)。將字段聲明為final
,以確保不可變性和線程安全性。
四. 小知識(shí)
4.1 使用@Autowired還會(huì)出現(xiàn)循環(huán)依賴的問(wèn)題么
使用 @Autowired 仍然可能會(huì)出現(xiàn)循環(huán)依賴的問(wèn)題。
Spring 容器在初始化時(shí)會(huì)先實(shí)例化所有的 bean,然后再進(jìn)行依賴注入。如果 A bean 依賴了 B bean,而 B bean 又依賴了 A bean,就會(huì)出現(xiàn)循環(huán)依賴的問(wèn)題。為了解決這個(gè)問(wèn)題,Spring 使用了三級(jí)緩存來(lái)處理循環(huán)依賴。當(dāng)容器在初始化 A bean 時(shí),如果發(fā)現(xiàn)它依賴了 B bean,就會(huì)先創(chuàng)建一個(gè) A bean 的代理對(duì)象,然后將代理對(duì)象放入第一級(jí)緩存中。接著容器會(huì)創(chuàng)建 B bean,并將其注入到 A bean 的代理對(duì)象中。最后再將 A bean 的代理對(duì)象注入到 B bean 中。但是,如果循環(huán)依賴的鏈條過(guò)長(zhǎng),就有可能導(dǎo)致 Spring 容器無(wú)法解決循環(huán)依賴的問(wèn)題,此時(shí)就會(huì)拋出 BeanCurrentlyInCreationException 異常。因此,在使用 @Autowired 進(jìn)行依賴注入時(shí),需要注意避免出現(xiàn)循環(huán)依賴的情況。
4.2 @Autowired 和 @Resource區(qū)別
- @Autowired 是 Spring 框架的注解,而 @Resource 是 JavaEE 的注解。
- @Autowired 默認(rèn)按照類型進(jìn)行匹配,如果有多個(gè)同類型的 bean,則可以通過(guò) @Qualifier 指定具體的 bean 名稱。而 @Resource 默認(rèn)按照名稱進(jìn)行匹配,如果名稱匹配不到,則可以通過(guò) name 屬性指定具體的 bean 名稱。
- @Autowired 可以用在構(gòu)造方法、setter 方法、字段上,而 @Resource 只能用在字段上。
- @Autowired 是 Spring 框架的特有功能,而 @Resource 是 JavaEE 的標(biāo)準(zhǔn)功能,在使用時(shí)需要注意兼容性問(wèn)題。
- 都可以用于依賴注入
到此這篇關(guān)于spring 和 idea 建議不要使用 @Autowired注解的文章就介紹到這了,更多相關(guān)spring和 idea 不使用 @Autowired注解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java編程中的性能優(yōu)化如何實(shí)現(xiàn)
這篇文章主要介紹了Java編程中的性能優(yōu)化如何實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10feign 如何獲取請(qǐng)求真實(shí)目的ip地址
這篇文章主要介紹了feign 獲取請(qǐng)求真實(shí)目的ip地址操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06spring?@Conditional的使用與擴(kuò)展源碼分析
這篇文章主要介紹了spring?@Conditional的使用與擴(kuò)展,這里需要注意如果Condition返回的是false,那么spirng就不會(huì)對(duì)方法或類進(jìn)行解析,具體源碼分析跟隨小編一起看看吧2022-03-03Java基于阻塞隊(duì)列實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模型示例詳解
這篇文章主要介紹了Java基于阻塞隊(duì)列實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模型,阻塞隊(duì)列的特點(diǎn)就是阻塞兩個(gè)字,阻塞功能使得生產(chǎn)者和消費(fèi)者兩端的能力得以平衡,當(dāng)有任何一端速度過(guò)快時(shí),阻塞隊(duì)列便會(huì)把過(guò)快的速度降下來(lái),感興趣的朋友可以參考下2023-12-12教你怎么用java一鍵自動(dòng)生成數(shù)據(jù)庫(kù)文檔
最近小編也在找這樣的插件,就是不想寫文檔了,浪費(fèi)時(shí)間和心情啊,果然我找到一款比較好用,操作簡(jiǎn)單不復(fù)雜.screw 是一個(gè)簡(jiǎn)潔好用的數(shù)據(jù)庫(kù)表結(jié)構(gòu)文檔的生成工具,支持 MySQL、Oracle、PostgreSQL 等主流的關(guān)系數(shù)據(jù)庫(kù).需要的朋友可以參考下2021-05-05java.lang.IllegalStateException:方法有太多主體參數(shù)問(wèn)題
這篇文章主要介紹了java.lang.IllegalStateException:方法有太多主體參數(shù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07解析rainbond以應(yīng)用為中心的架構(gòu)設(shè)計(jì)原理
這篇文章主要為大家介紹了rainbond以應(yīng)用為中心的架構(gòu)設(shè)計(jì)實(shí)現(xiàn)及原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-02-02SpringBoot上傳文件大小受限問(wèn)題的解決辦法
最近有一次由于項(xiàng)目升級(jí)發(fā)現(xiàn)了一個(gè)上傳方面的問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于SpringBoot上傳文件大小受限問(wèn)題的解決辦法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05Spring+Mybatis 實(shí)現(xiàn)aop數(shù)據(jù)庫(kù)讀寫分離與多數(shù)據(jù)庫(kù)源配置操作
這篇文章主要介紹了Spring+Mybatis 實(shí)現(xiàn)aop數(shù)據(jù)庫(kù)讀寫分離與多數(shù)據(jù)庫(kù)源配置操作,需要的朋友可以參考下2017-09-09