Field injection is not recommended

文章目錄

  • 1. 引言
  • 2. 不推薦使用@Autowired的原因
  • 3. Spring提供了三種主要的依賴注入方式
    • 3.1. 構造函數注入(Constructor Injection)
    • 3.2. Setter方法注入(Setter Injection)
    • 3.3. 字段注入(Field Injection)
  • 4. 推薦方案
  • 5. 參考博客

1. 引言

Field injection is not recommended

意思就是不推薦使用字段注入的方式,不是不推薦@Autowired注解,以前為了簡便就直接使用
@Resource代替,程序員都在不斷追求完美。。。 接下來我們實實在在的分析一下為啥不推薦,以及到底推薦那種方式注入。

2. 不推薦使用@Autowired的原因

不推薦使用@Autowired進行字段注入的原因有以下幾點:

  1. 緊耦合性(Tight Coupling):字段注入將依賴關系直接注入到類的字段上,導致類與依賴之間產生緊密的耦合。這使得代碼難以修改和擴展,并且增加了對具體實現的依賴性。

  2. 隱藏依賴關系(Hidden Dependencies):字段注入隱藏了類的依賴關系,使代碼不夠透明和可讀。讀取代碼時無法立即知道類所依賴的其他組件或服務。

  3. 單元測試困難(Difficult Unit Testing):由于字段注入需要依賴容器來自動注入依賴項,導致在編寫單元測試時必須依賴完整的容器環境。這增加了測試的復雜性,并且可能會導致測試變慢或不穩定。

  4. 難以發現依賴問題(Dependency Issues):字段注入使得依賴可以在運行時更改,這增加了代碼維護的復雜性。同時,如果依賴項沒有正確配置或不存在,就會在運行時出現錯誤,而不是在編譯時就能發現。

相比之下,構造器注入(Constructor Injection)或Setter方法注入(Setter Injection)提供了更好的可測試性、可維護性和代碼清晰度。它們明確列出了類所需的依賴項,并使得依賴關系更加透明和易于理解。這些方法也更容易進行單元測試,且不需要依賴完整的容器環境。

3. Spring提供了三種主要的依賴注入方式

3.1. 構造函數注入(Constructor Injection)

通過構造函數將依賴項傳遞給目標類。這種方式明確聲明了類所需的依賴項,并且使得類的實例在創建時就具備了必要的依賴關系。示例代碼如下:

@Component
public class SLFBClient {private final DataSourceFactory dataSourceFactory;/*** @Autowired 從spring4.3開始可以省略*/
//    @Autowiredpublic SLFBClient(DataSourceFactory dataSourceFactory) {this.dataSourceFactory = dataSourceFactory;}}

3.2. Setter方法注入(Setter Injection)

通過Setter方法設置依賴項。這種方式允許使用默認構造函數創建類的實例,然后通過Setter方法來動態設置依賴項。示例代碼如下:

@Component
public class SLFBClient {private  DataSourceFactory dataSourceFactory;/*** @Autowired 從spring4.3開始可以省略*/
//    @Autowiredpublic void setDataSourceFactory(DataSourceFactory dataSourceFactory) {this.dataSourceFactory = dataSourceFactory;}
}

3.3. 字段注入(Field Injection)

通過直接將依賴項注入到類的字段上。這種方式最簡潔,但也最不推薦使用(在之前的回答中已經詳細解釋了原因)。示例代碼如下:

@Component
public class SLFBClient {//    @Autowired
//    @Resource@Injectprivate DataSourceFactory dataSourceFactory;}

@Autowired、@Resource和@Inject是用于依賴注入的常見注解,它們在使用方式和一些細節上有一些區別。

  1. @Autowired:

    • 來自Spring框架。
    • 默認按照類型(byType)進行依賴注入,會嘗試將匹配的bean自動注入到目標字段、構造函數或方法參數中。
    • 可以與@Qualifier一起使用,通過指定bean的名稱或限定符來進一步指定要注入的bean。
    • @Autowired是非強制性的,可以在某些情況下將依賴項標記為可選。
  2. @Resource:

    • Java EE的標準注解,也可以被Spring框架支持。
    • 默認按照名稱(byName)進行依賴注入,通過指定bean的名稱來解析并注入匹配的bean
    • 可以使用name屬性指定要注入的bean的名稱。
    • @Resource是強制性的,要求找到匹配的bean進行注入,否則會拋出異常。
  3. @Inject:

    • Java CDI(Contexts and Dependency Injection)規范的一部分,可以由Java EE和一些其他框架(如Spring)支持。
    • 默認按照類型(byType)進行依賴注入,使用與@Autowired類似的機制。
    • 不支持required屬性,即所有注入都被視為必需的。
    • 可以與@Qualifier一起使用,通過指定bean的名稱或限定符來進一步指定要注入的bean

總結:

  • @AutowiredSpring特有的注解,默認按類型進行依賴注入。
  • @ResourceJava EE的標準注解,可被Spring支持,默認按名稱進行依賴注入。
  • @InjectJava CDI規范的注解,也可被Spring等框架支持,默認按類型進行依賴注入。
  • 三個注解都可以與@Qualifier一起使用來指定具體要注入的bean
  • @Autowired@Inject在功能上相似,而@Resource功能稍有不同,但它們通常可以互相替代使用。

需要注意的是,具體在Spring中使用哪個注解,可以根據項目的需求、框架的支持以及個人偏好來決定。

4. 推薦方案

使用構造器注入的好處:

  • 保證依賴不可變(final關鍵字)
  • 保證依賴不為空(省去了我們對其檢查)
  • 保證返回客戶端(調用)的代碼的時候是完全初始化的狀態
  • 避免了循環依賴
  • 提升了代碼的可復用性

推薦使用Lombok中的@RequiredArgsConstructor注解

@Component
@RequiredArgsConstructor
public class SLFBClient {private final DataSourceFactory dataSourceFactory;}

接下來我們探討一下Lombok@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsContructor三個注解

  1. @NoArgsConstructor:
    • 自動生成一個無參構造函數。
    • 適用于不需要傳入參數的情況。
import lombok.NoArgsConstructor;@NoArgsConstructor
public class MyClass {// Fields and methods
}

2. @RequiredArgsConstructor:

  • 自動生成一個包含所有被標記為final和@NonNull的字段的構造函數。
  • 適用于只關注部分字段并確保這些字段非空的情況。
import lombok.NonNull;
import lombok.RequiredArgsConstructor;@RequiredArgsConstructor
public class MyClass {private final String name;@NonNullprivate final Integer age;// Other fields and methods
}
  1. @AllArgsConstructor:
    • 自動生成一個包含所有類字段的構造函數。
    • 適用于需要一次性傳遞所有字段值的情況。
import lombok.AllArgsConstructor;@AllArgsConstructor
public class MyClass {private String name;private int age;// Other fields and methods
}

5. 參考博客

Field Dependency Injection Considered Harmful

Field injection is not recommended(Spring團隊不推薦使用Field注入)

【Spring】淺談spring為什么推薦使用構造器注入

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/39412.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/39412.shtml
英文地址,請注明出處:http://en.pswp.cn/news/39412.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

03 QT基本控件和功能類

一 進度條 、水平滑動條 垂直滑動條 當在QT中,在已知類名的情況下,要了解類的構造函數 常用屬性 及 信號和槽 常用api 特征:可以獲取當前控件的值和設置它的當值 ---- int ui->progressBar->setValue(value); //給進度條設置一個整型值 ui->progressBar->value…

計算機視覺五大核心研究任務全解:分類識別、檢測分割、人體分析、三維視覺、視頻分析

目錄 一、引言1.1 計算機視覺的定義1.1.1 核心技術1.1.2 應用場景 1.2 歷史背景及發展1.2.1 1960s-1980s: 初期階段1.2.2 1990s-2000s: 機器學習時代1.2.3 2010s-現在: 深度學習的革命 1.3 應用領域概覽1.3.1 工業自動化1.3.2 醫療圖像分析1.3.3 自動駕駛1.3.4 虛擬現實與增強現…

【Linux】進程調度

進程調度 硬件向OS發送時間中斷 --> 系統時鐘硬件會進行時間計數,每隔一段很短的時間會向OS發送時鐘中斷,處理中斷,檢測進程時間片 --> 收到中斷,OS就會不斷定期地執行對應的時鐘中斷處理方法,檢查當前進程的時…

山東布谷科技直播軟件開發WebRTC技術:建立實時通信優質平臺

在數字化的時代,實時通信成為了人們遠程交流的主要方式,目前市場上也出現了很多帶有實時通信交流的軟件,實時通信符合人們現在的需求,所以在直播軟件開發過程中,開發者也運用了實時通信技術為直播軟件加入了實時通信的…

【計算機視覺|生成對抗】生成對抗網絡(GAN)

本系列博文為深度學習/計算機視覺論文筆記,轉載請注明出處 標題:Generative Adversarial Nets 鏈接:Generative Adversarial Nets (nips.cc) 摘要 我們提出了一個通過**對抗(adversarial)**過程估計生成模型的新框架…

mybatisplus學習筆記

1.踩過的坑 1.MybatisPlus 要與其代碼生成器的版本一致; 2.要使用新版代碼(3.5.1及以上)生成器則要使用springboot3,如果用springboot2使用新版代碼生成器會導致builder.parent(“com.sdfsf”) // 設置父包名》重復!&…

2.阿里云對象存儲OSS

1.對象存儲概述 文件上傳,是指將本地圖片、視頻、音頻等文件上傳到服務器上,可以供其他用戶瀏覽或下載的過程。文件上傳在項目中應用非常廣泛,我們經常發抖音、發朋友圈都用到了文件上傳功能。 實現文件上傳服務,需要有存儲的支持…

【概念理解】STM32中的sprintf()函數

sprintf()函數 這個函數在 stdio.h中;可以將格式化的數據寫入到一個字符串緩沖區中。 int sprintf(char *str, const char *format, ...);str:指向字符數組的指針,即用于存儲格式化后字符串的緩沖區。format:格式化字符串&#…

(十六)大數據實戰——安裝使用mysql版的hive服務

前言 hive默認使用的是內嵌據庫derby,Derby 是一個嵌入式數據庫,可以輕松地以庫的形式集成到應用程序中。它不需要獨立的服務器進程,所有的數據存儲在應用程序所在的文件系統中。為了支持hive服務更方便的使用,我們使用mysql數據…

Centos 8和Centos 7中配置阿里云的 yum 源

YUM源簡介 yum是一種在Linux環境下安裝、更新和刪除軟件包的軟件管理器。通過yum,用戶可以輕松地從軟件倉庫中搜索和安裝包含所需軟件的軟件包,并自動處理所需的依賴關系。此外,yum還可以與其他軟件管理工具配合使用,例如rpm。它…

【實戰】十一、看板頁面及任務組頁面開發(一) —— React17+React Hook+TS4 最佳實踐,仿 Jira 企業級項目(二十三)

文章目錄 一、項目起航:項目初始化與配置二、React 與 Hook 應用:實現項目列表三、TS 應用:JS神助攻 - 強類型四、JWT、用戶認證與異步請求五、CSS 其實很簡單 - 用 CSS-in-JS 添加樣式六、用戶體驗優化 - 加載中和錯誤狀態處理七、Hook&…

c語言每日一練(8)

前言:每日一練系列,每一期都包含5道選擇題,2道編程題,博主會盡可能詳細地進行講解,令初學者也能聽的清晰。每日一練系列會持續更新,暑假時三天之內必有一更,到了開學之后,將看學業情…

【javaweb】學習日記Day1 - HTML CSS入門

目錄 一、圖片標簽 ① 絕對路徑 1.絕對磁盤路徑 2.絕對網絡路徑 ② 相對路徑 (推薦) 二、標題標簽 三、水平線標簽 四、標題樣式 1、CSS引入樣式 ① 行內樣式 ② 內嵌樣式 ③ 外嵌樣式 2、CSS選擇器 ① 元素選擇器 ② id選擇器 ③…

Hadoop+Python+Django+Mysql熱門旅游景點數據分析系統的設計與實現(包含設計報告)

系統闡述的是使用熱門旅游景點數據分析系統的設計與實現,對于Python、B/S結構、MySql進行了較為深入的學習與應用。主要針對系統的設計,描述,實現和分析與測試方面來表明開發的過程。開發中使用了 django框架和MySql數據庫技術搭建系統的整體…

Python批量給excel文件加密

有時候我們需要定期給公司外部發郵件,在自動化發郵件的時候需要對文件進行加密傳輸。本文和你一起來探索用python給單個文件和批量文件加密。 ?? python自動化發郵件可參考【干貨】用Python每天定時發送監控郵件。 文章目錄 一、安裝pypiwin32包二、定義給excel加…

【Docker】Docker使用之容器技術發展史

🎬 博客主頁:博主鏈接 🎥 本文由 M malloc 原創,首發于 CSDN🙉 🎄 學習專欄推薦:LeetCode刷題集 🏅 歡迎點贊 👍 收藏 ?留言 📝 如有錯誤敬請指正&#xff0…

【Unity】UI的一些簡單知識

Canvas 新建一個Canvas Render Mode Canvas 中有一個Render Mode(渲染模式),有三種渲染模式: Screen Space-Overlay (屏幕空間)Screen Space-Camara 、 World Space 其中,Space- Overlay是默認顯示在…

使用Spring Boot和Redis實現用戶IP接口限流的詳細指南

系列文章目錄 文章目錄 系列文章目錄前言一、準備工作二、編寫限流過濾器三、配置Redis四、測試接口限流總結 前言 在高并發場景下,為了保護系統免受惡意請求的影響,接口限流是一項重要的安全措施。本文將介紹如何使用Spring Boot和Redis來實現用戶IP的…

數據統計與可視化的Dash應用程序

在數據分析和可視化領域,Dash是一個強大的工具,它結合了Python中的數據處理庫(如pandas)和交互式可視化庫(如Plotly)以及Web應用程序開發框架。本文將介紹如何使用Dash創建一個簡單的數據統計和可視化應用程…

移動端網頁中的前端視頻技術探索

引言 隨著移動設備的普及和網絡速度的提升,移動端網頁中的視頻播放已經成為了越來越重要的功能需求。本篇博客將介紹一些在移動端網頁中實現前端視頻播放的技術探索,并提供詳細的代碼示例。 1. 基本視頻標簽 在移動端網頁中實現視頻播放最基本的方法就…