最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot字段注入和構(gòu)造函數(shù)注入的區(qū)別及說(shuō)明

 更新時(shí)間:2025年04月07日 08:54:02   作者:我就是我500  
這篇文章主要介紹了SpringBoot字段注入和構(gòu)造函數(shù)注入的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

文章背景

在使用Spring開(kāi)發(fā)項(xiàng)目時(shí),我們經(jīng)常需要使用依賴注入來(lái)管理對(duì)象之間的依賴關(guān)系。Spring提供了多種依賴注入方式,如構(gòu)造函數(shù)注入、Setter方法注入和字段注入等。

這些方式各有優(yōu)缺點(diǎn),需要根據(jù)具體情況選擇合適的注入方式。

在本文中,我將分享我在開(kāi)發(fā)過(guò)程中遇到的一些問(wèn)題,以及我對(duì)這些問(wèn)題的思考和解決方法。

主要涉及以下幾個(gè)方面:

  • 字段注入和構(gòu)造函數(shù)注入的區(qū)別和聯(lián)系
  • 為什么字段注入和Setter方法注入不會(huì)導(dǎo)致循環(huán)依賴的問(wèn)題,而構(gòu)造函數(shù)注入會(huì)導(dǎo)致循環(huán)依賴的問(wèn)題
  • 為什么Spring不推薦使用字段注入,而推薦使用構(gòu)造函數(shù)注入

通過(guò)本文,我希望能夠幫助大家更好地理解Spring的依賴注入原理和實(shí)踐,以及如何避免一些常見(jiàn)的問(wèn)題和錯(cuò)誤。

什么是字段注入和構(gòu)造函數(shù)注入?

在SpringBoot中,我們可以使用@Autowired注解來(lái)實(shí)現(xiàn)依賴注入,即讓Spring容器自動(dòng)為我們的類(lèi)提供所需的對(duì)象。

有三種常見(jiàn)的注入方式:字段注入,Setter方法注入和構(gòu)造函數(shù)注入。

  • 字段注入:直接在類(lèi)的屬性上使用@Autowired注解,無(wú)需編寫(xiě)額外的代碼。
  • Setter方法注入:在類(lèi)的Setter方法上使用@Autowired注解,需要編寫(xiě)相應(yīng)的Setter方法。
  • 構(gòu)造函數(shù)注入:在類(lèi)的構(gòu)造函數(shù)上使用@Autowired注解,需要編寫(xiě)相應(yīng)的構(gòu)造函數(shù)。

下面是一個(gè)簡(jiǎn)單的例子,假設(shè)我們有一個(gè)UserService接口和一個(gè)UserServiceImpl實(shí)現(xiàn)類(lèi),以及一個(gè)UserController類(lèi),我們想要在UserController中使用UserService對(duì)象。

// UserService接口
public interface UserService {
    void saveUser(User user);
}

// UserServiceImpl實(shí)現(xiàn)類(lèi)
@Service
public class UserServiceImpl implements UserService {
    @Override
    public void saveUser(User user) {
        // 保存用戶到數(shù)據(jù)庫(kù)
    }
}

// UserController類(lèi)
@Controller
public class UserController {
    // 字段注入
    @Autowired
    private UserService userService;

    // Setter方法注入
    // private UserService userService;
    // @Autowired
    // public void setUserService(UserService userService) {
    //     this.userService = userService;
    // }

    // 構(gòu)造函數(shù)注入
    // private final UserService userService;
    // @Autowired
    // public UserController(UserService userService) {
    //     this.userService = userService;
    // }

    public void createUser(User user) {
        userService.saveUser(user);
        // 其他邏輯
    }
}

這兩種方式有什么區(qū)別?

這兩種方式在功能上沒(méi)有區(qū)別,都可以實(shí)現(xiàn)依賴注入。但是在一些細(xì)節(jié)上有一些差異,主要有以下幾點(diǎn) :

  • 可讀性:字段注入的代碼更簡(jiǎn)潔,依賴項(xiàng)被隔離在一個(gè)地方,更容易閱讀。構(gòu)造函數(shù)注入的代碼更冗長(zhǎng),當(dāng)有多個(gè)依賴項(xiàng)時(shí),構(gòu)造函數(shù)可能會(huì)變得臃腫。
  • 不變性:構(gòu)造函數(shù)注入支持不變性,即可以將依賴項(xiàng)聲明為final類(lèi)型,保證對(duì)象創(chuàng)建后不會(huì)被修改。這有利于線程安全性,狀態(tài)安全性和可讀性。字段注入不支持不變性,無(wú)法將依賴項(xiàng)聲明為final類(lèi)型。
  • 狀態(tài)安全性:構(gòu)造函數(shù)注入保證了對(duì)象被實(shí)例化為完整狀態(tài)或完全不被實(shí)例化。如果使用者使用new關(guān)鍵字創(chuàng)建對(duì)象,則必須提供所有依賴項(xiàng)作為參數(shù)。字段注入無(wú)法保證狀態(tài)安全性,如果使用者使用new關(guān)鍵字創(chuàng)建對(duì)象,則無(wú)法設(shè)置對(duì)象的狀態(tài)。唯一的選擇是使用反射設(shè)置私有字段。
  • 循環(huán)依賴:循環(huán)依賴是指兩個(gè)或多個(gè)類(lèi)相互依賴對(duì)方,導(dǎo)致無(wú)法正常創(chuàng)建對(duì)象。例如,如果A類(lèi)依賴B類(lèi),B類(lèi)依賴A類(lèi),則會(huì)產(chǎn)生循環(huán)依賴。循環(huán)依賴是一種不良的設(shè)計(jì)模式,應(yīng)該避免。

字段注入和Setter方法注入的聯(lián)系

字段注入和Setter方法注入都是通過(guò)反射來(lái)實(shí)現(xiàn)的,它們都可以在類(lèi)的屬性上使用@Autowired注解來(lái)標(biāo)注依賴關(guān)系。

它們的區(qū)別在于,字段注入是直接在屬性上使用@Autowired注解,而Setter方法注入是在屬性對(duì)應(yīng)的Setter方法上使用@Autowired注解。

字段注入和Setter方法注入的聯(lián)系有以下幾點(diǎn):

  • 它們都是基于名稱或者類(lèi)型來(lái)匹配依賴關(guān)系的。如果屬性名字或者Setter方法名字與Bean定義中的id或者name相同,則按照名稱匹配;否則按照屬性類(lèi)型或者Setter方法參數(shù)類(lèi)型匹配。
  • 它們都不支持不變性,即無(wú)法將依賴項(xiàng)聲明為final類(lèi)型。這可能會(huì)導(dǎo)致線程安全性,狀態(tài)安全性和可讀性的問(wèn)題。
  • 它們都可以避免循環(huán)依賴的問(wèn)題,因?yàn)樗鼈兪窃趯?duì)象創(chuàng)建后才進(jìn)行依賴注入的,而不是在對(duì)象創(chuàng)建時(shí)。這樣可以避免構(gòu)造函數(shù)注入時(shí)可能出現(xiàn)的循環(huán)依賴異常。

為什么字段注入和Setter方法注入不會(huì)導(dǎo)致循環(huán)依賴的問(wèn)題?

循環(huán)依賴是指兩個(gè)或多個(gè)類(lèi)相互依賴對(duì)方,導(dǎo)致無(wú)法正常創(chuàng)建對(duì)象。例如,如果A類(lèi)依賴B類(lèi),B類(lèi)依賴A類(lèi),則會(huì)產(chǎn)生循環(huán)依賴。循環(huán)依賴是一種不良的設(shè)計(jì)模式,應(yīng)該避免。

在Spring中,循環(huán)依賴主要發(fā)生在構(gòu)造函數(shù)注入的情況下,因?yàn)闃?gòu)造函數(shù)注入是在對(duì)象創(chuàng)建時(shí)就進(jìn)行依賴注入的,而不是在對(duì)象創(chuàng)建后。這樣就會(huì)導(dǎo)致一個(gè)死鎖的情況,即A類(lèi)要等待B類(lèi)創(chuàng)建完成才能創(chuàng)建,而B(niǎo)類(lèi)又要等待A類(lèi)創(chuàng)建完成才能創(chuàng)建。

字段注入和Setter方法注入不會(huì)導(dǎo)致循環(huán)依賴的問(wèn)題,因?yàn)樗鼈兪窃趯?duì)象創(chuàng)建后才進(jìn)行依賴注入的,而不是在對(duì)象創(chuàng)建時(shí)。這樣就可以避免死鎖的情況,即A類(lèi)和B類(lèi)都可以先創(chuàng)建出來(lái),然后再互相注入對(duì)方。

Spring解決循環(huán)依賴的方法是通過(guò)提前暴露半成品對(duì)象(Early-Stage Object)來(lái)解決。半成品對(duì)象是指已經(jīng)實(shí)例化但還沒(méi)有完成初始化的對(duì)象。Spring會(huì)將半成品對(duì)象放入一個(gè)緩存中,當(dāng)其他對(duì)象需要依賴它時(shí),就可以從緩存中獲取它,并進(jìn)行后續(xù)的屬性賦值和初始化操作。

簡(jiǎn)述兩種方式的流程

字段注入和構(gòu)造函數(shù)注入的流程如下:

  • 字段注入:當(dāng)IOC容器創(chuàng)建Bean時(shí),它會(huì)先通過(guò)反射調(diào)用無(wú)參構(gòu)造函數(shù)來(lái)實(shí)例化對(duì)象,然后再通過(guò)反射獲取屬性上的@Autowired注解,并根據(jù)名稱或者類(lèi)型來(lái)匹配依賴關(guān)系,最后通過(guò)反射將依賴關(guān)系注入到屬性中。
  • 構(gòu)造函數(shù)注入:當(dāng)IOC容器創(chuàng)建Bean時(shí),它會(huì)先通過(guò)反射獲取構(gòu)造函數(shù)上的@Autowired注解,并根據(jù)名稱或者類(lèi)型來(lái)匹配依賴關(guān)系,然后再通過(guò)反射調(diào)用帶參構(gòu)造函數(shù)來(lái)實(shí)例化對(duì)象,并將依賴關(guān)系作為參數(shù)傳遞進(jìn)去。

為什么Spring不推薦使用字段注入?

Spring不推薦使用字段注入的原因有以下幾點(diǎn):

  • 字段注入違反了單一職責(zé)原則,因?yàn)樗沟锰砑有碌囊蕾図?xiàng)非常容易,而不會(huì)引起警告。這可能導(dǎo)致類(lèi)有太多的責(zé)任和關(guān)注點(diǎn),需要進(jìn)一步的檢查和重構(gòu)。
  • 字段注入隱藏了依賴關(guān)系,因?yàn)樗鼪](méi)有使用公共接口(方法或構(gòu)造函數(shù))來(lái)清楚地與依賴項(xiàng)通信。這樣就不利于類(lèi)的可測(cè)試性和可重用性,也不利于依賴項(xiàng)的可選性和強(qiáng)制性的區(qū)分。
  • 字段注入導(dǎo)致了依賴注入容器的耦合,因?yàn)樗沟妙?lèi)無(wú)法脫離容器獨(dú)立運(yùn)行。這意味著類(lèi)不能通過(guò)new關(guān)鍵字來(lái)創(chuàng)建,也不能切換到其他的依賴注入框架。
  • 字段注入不支持不變性,因?yàn)樗鼰o(wú)法將依賴項(xiàng)聲明為final類(lèi)型,也無(wú)法注入靜態(tài)變量。這可能會(huì)導(dǎo)致線程安全性,狀態(tài)安全性和可讀性的問(wèn)題。

總結(jié)

字段注入和構(gòu)造函數(shù)注入都是Spring中常用的依賴注入方式,它們各有優(yōu)缺點(diǎn),開(kāi)發(fā)人員應(yīng)根據(jù)具體情況選擇合適的注入方式。

一般來(lái)說(shuō),以下幾點(diǎn)可以作為參考:

  • 如果依賴關(guān)系是必須的,且不需要重新配置或者重新注入,則推薦使用構(gòu)造函數(shù)注入,因?yàn)樗梢灾С植蛔冃院蜖顟B(tài)安全性。
  • 如果依賴關(guān)系是可選的,或者需要重新配置或者重新注入,則推薦使用字段注入或者Setter方法注入,因?yàn)樗鼈兛梢蕴岣叽a的簡(jiǎn)潔性和靈活性。
  • 如果有循環(huán)依賴的問(wèn)題,則不能使用構(gòu)造函數(shù)注入,只能使用字段注入或者Setter方法注入,因?yàn)樗鼈兛梢员苊馑梨i的情況。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中實(shí)現(xiàn)漢字生成拼音首拼和五筆碼

    Java中實(shí)現(xiàn)漢字生成拼音首拼和五筆碼

    這篇文章主要介紹了Java中實(shí)現(xiàn)漢字生成拼音首拼和五筆碼方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java掌握本地與網(wǎng)絡(luò)日志技術(shù)方式

    Java掌握本地與網(wǎng)絡(luò)日志技術(shù)方式

    本文將深入探討本地日志與網(wǎng)絡(luò)日志的區(qū)別,分析網(wǎng)絡(luò)日志的適用場(chǎng)景,并以 Log4j 為例詳細(xì)介紹如何實(shí)現(xiàn)網(wǎng)絡(luò)日志記錄,我們將提供易于理解的代碼示例,并分享最佳實(shí)踐,以幫助開(kāi)發(fā)者在 Java 應(yīng)用程序中有效實(shí)施日志記錄策略
    2025-05-05
  • 一篇文章帶你徹底搞懂Java日志與Logback

    一篇文章帶你徹底搞懂Java日志與Logback

    Logback是一個(gè)開(kāi)源的日志框架,Logback旨在提供比log4j更高效、更靈活的日志解決方案,這篇文章主要介紹了Java日志與Logback的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2026-04-04
  • JAVA 多態(tài)操作----父類(lèi)與子類(lèi)轉(zhuǎn)換問(wèn)題實(shí)例分析

    JAVA 多態(tài)操作----父類(lèi)與子類(lèi)轉(zhuǎn)換問(wèn)題實(shí)例分析

    這篇文章主要介紹了JAVA 多態(tài)操作----父類(lèi)與子類(lèi)轉(zhuǎn)換問(wèn)題,結(jié)合實(shí)例形式分析了JAVA 多態(tài)操作中父類(lèi)與子類(lèi)轉(zhuǎn)換問(wèn)題相關(guān)原理、操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2020-05-05
  • Spring MVC深入學(xué)習(xí)之啟動(dòng)初始化過(guò)程

    Spring MVC深入學(xué)習(xí)之啟動(dòng)初始化過(guò)程

    最近因?yàn)楣ぷ鞯脑蛟趯W(xué)習(xí)Spring MVC,為了更深入的學(xué)習(xí)Spring MVC,下面這篇文章主要給大家介紹了關(guān)于Spring MVC深入學(xué)習(xí)之啟動(dòng)初始化過(guò)程的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-07-07
  • Maven中pom.xml配置文件詳細(xì)介紹

    Maven中pom.xml配置文件詳細(xì)介紹

    這篇文章主要介紹了Maven中pom.xml配置文件詳細(xì)介紹,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Ajax實(shí)現(xiàn)搜索引擎自動(dòng)補(bǔ)全功能

    Ajax實(shí)現(xiàn)搜索引擎自動(dòng)補(bǔ)全功能

    本文主要介紹了Ajax實(shí)現(xiàn)搜索引擎自動(dòng)補(bǔ)全功能的實(shí)例解析。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-04-04
  • Spring boot部署發(fā)布到linux的操作方法

    Spring boot部署發(fā)布到linux的操作方法

    這篇文章主要介紹了Spring boot部署發(fā)布到linux的操作方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-05-05
  • SpringBoot+Mybatis plus實(shí)現(xiàn)多數(shù)據(jù)源整合的實(shí)踐

    SpringBoot+Mybatis plus實(shí)現(xiàn)多數(shù)據(jù)源整合的實(shí)踐

    本文主要介紹了SpringBoot+Mybatis plus實(shí)現(xiàn)多數(shù)據(jù)源整合的實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • SpringCloud中的Hystrix保護(hù)機(jī)制詳解

    SpringCloud中的Hystrix保護(hù)機(jī)制詳解

    這篇文章主要介紹了SpringCloud中的Hystrix保護(hù)機(jī)制詳解,Hystrix,英文意思是豪豬,全身是刺,看起來(lái)就不好惹,是一種保護(hù)機(jī)制,Hystrix也是Netflix公司的一款組件,需要的朋友可以參考下
    2023-12-12

最新評(píng)論

海盐县| 当雄县| 江门市| 安龙县| 大化| 临海市| 桂平市| 沂水县| 石屏县| 尼勒克县| 建平县| 专栏| 蒙自县| 泽库县| 连山| 乡城县| 福鼎市| 彩票| 台山市| 盘锦市| 且末县| 横峰县| 峨山| 项城市| 琼结县| 沂水县| 佛坪县| 尚义县| 红安县| 绿春县| 肃南| 北宁市| 宁波市| 塘沽区| 陆丰市| 克拉玛依市| 土默特左旗| 江门市| 浦县| 南岸区| 桂阳县|