欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

文章背景

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

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

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

主要涉及以下幾個方面:

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

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

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

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

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

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

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

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

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

// UserController類
@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ū)別?

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

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

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

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

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

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

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

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

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

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

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

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

簡述兩種方式的流程

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

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

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

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

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

總結(jié)

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

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

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

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

相關(guān)文章

  • Java如何判斷一個空對象的常見方法

    Java如何判斷一個空對象的常見方法

    在Java中判斷對象是否為空是一項(xiàng)重要的編程技巧,可以有效防止空指針異常的發(fā)生,下面這篇文章主要給大家介紹了關(guān)于利用Java如何判斷一個空對象的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • java實(shí)現(xiàn)異步導(dǎo)出數(shù)據(jù)

    java實(shí)現(xiàn)異步導(dǎo)出數(shù)據(jù)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)異步導(dǎo)出數(shù)據(jù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • Mybatis使用useGeneratedKeys獲取自增主鍵的方法

    Mybatis使用useGeneratedKeys獲取自增主鍵的方法

    這篇文章主要給大家介紹了關(guān)于Mybatis使用useGeneratedKeys獲取自增主鍵的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Mybatis具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Mybatis 中 Oracle 的拼接模糊查詢及用法詳解

    Mybatis 中 Oracle 的拼接模糊查詢及用法詳解

    這篇文章主要介紹了Mybatis 中 Oracle 的拼接模糊查詢及用法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-08-08
  • Java數(shù)據(jù)結(jié)構(gòu)之循環(huán)隊(duì)列簡單定義與用法示例

    Java數(shù)據(jù)結(jié)構(gòu)之循環(huán)隊(duì)列簡單定義與用法示例

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)之循環(huán)隊(duì)列簡單定義與用法,簡要描述了循環(huán)隊(duì)列的概念、原理,并結(jié)合實(shí)例形式分析了java循環(huán)隊(duì)列的定義與使用方法,需要的朋友可以參考下
    2017-10-10
  • SpringBoot + vue2.0查詢所用功能詳解

    SpringBoot + vue2.0查詢所用功能詳解

    這篇文章主要介紹了SpringBoot + vue2.0查詢所用功能,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-11-11
  • Java圖形化界面設(shè)計(jì)之布局管理器之BorderLayout案例詳解

    Java圖形化界面設(shè)計(jì)之布局管理器之BorderLayout案例詳解

    這篇文章主要介紹了Java圖形化界面設(shè)計(jì)之布局管理器之BorderLayout案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • WebSocket整合SSM(Spring,Struts2,Maven)的實(shí)現(xiàn)示例

    WebSocket整合SSM(Spring,Struts2,Maven)的實(shí)現(xiàn)示例

    這篇文章主要介紹了WebSocket整合SSM(Spring,Struts2,Maven)的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • Java通過JsApi方式實(shí)現(xiàn)微信支付

    Java通過JsApi方式實(shí)現(xiàn)微信支付

    本文講解了Java如何實(shí)現(xiàn)JsApi方式的微信支付,代碼內(nèi)容詳細(xì),文章思路清晰,需要的朋友可以參考下
    2015-07-07
  • 最最常用的 100 個 Java類分享

    最最常用的 100 個 Java類分享

    這篇文章主要介紹了最最常用的 100 個 Java類分享,需要的朋友可以參考下
    2015-04-04

最新評論