【注解使用】使用@Autowired后提示:Field injection is not recommended(Spring團隊不推薦使用Field注入)

?問題發生場景:

在使用 IDEA 開發 SpringBoot 項目時,在?Controller?類中使用注解?@Autowired?注入一個依賴出現了警告提示,查看其他使用該注解的地方同樣出現了警告提示。這是怎么回事?由于先去使用了SpringBoot并沒有對Spring進行系統性學習,所以做一個記錄。

Field injection is not recommended(不再推薦使用字段注入)?

因為功力有限,所以以下內容均來自別人的博客:

Field injection is not recommended(Spring團隊不推薦使用Field注入)_編程火箭車的博客-CSDN博客

為什么不推薦使用Field注入

  • 違反單一責任原則

添加新的依賴項非常容易。添加6個、10個甚至12個依賴項沒有問題。當使用構造函數注入時,在某一點之后,構造函數參數的數量會變得過高,并且很明顯會出現問題。依賴太多通常意味著類有太多的責任。這可能違反了單一職責原則和關注點分離,這表明類需要進一步的檢查和重構。當直接注入字段時,沒有這樣的警告,因為這種方法可以無限擴展。

  • 依賴隱藏

使用依賴注入容器意味著類不再負責管理自己的依賴項。獲取依賴項的職責是從類中提取的。由其他人現在負責提供依賴項——依賴注入容器或在測試中手動分配它們。當類不再負責獲取其依賴項時,它應該使用公共接口(方法或構造函數)清楚地與它們通信。這樣就可以清楚類需要什么,以及它是可選的(Setter)還是強制的(構造函數)。

  • 依賴注入容器耦合

DI 框架的核心思想之一是托管類不應該依賴于所使用的 DI 容器。換句話說,它應該只是一個普通的 POJO,可以獨立地實例化它,前提是將所有必需的依賴項傳遞給它。通過這種方式,可以在單元測試中實例化它,而不需要啟動 DI 容器,并單獨測試它(使用的容器更像是集成測試)。如果沒有容器耦合,則可以將該類作為托管或非托管類使用,甚至可以切換到新的 DI 框架。

然而,當直接注入字段時,無法直接用所有需要的依賴項實例化類。這意味著:

  • 有一種方法(通過調用默認構造函數)可以在一個狀態中使用 new 關鍵字來創建一個對象,該狀態中缺少一些強制協作者,使用將導致 NullPointerException。
  • 這樣的類不能在 DI 容器(測試、其他模塊)之外重用,因為除了反射之外,沒有其他方法為它提供所需的依賴項。
  • 不變性

與構造函數不同,Field 注入不能用于將依賴項分配給最終字段。

那Spring團隊推薦什么注入方式呢?

推薦構造器注入

官方文檔里的說法:Core Technologies

Constructor-based or setter-based DI?

Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for?mandatory dependencies?and setter methods or configuration methods for?optional dependencies. Note that use of the?@Required?annotation on a setter method can be used to make the property a required dependency.

The Spring team generally advocates constructor injection as it enables one to implement application components as?immutable objects?and to ensure that required dependencies are not?null. Furthermore constructor-injected components are always returned to client (calling) code in a fully initialized state. As a side note, a large number of constructor arguments is a?bad code smell, implying that the class likely has too many responsibilities and should be refactored to better address proper separation of concerns.

Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class. Otherwise, not-null checks must be performed everywhere the code uses the dependency. One benefit of setter injection is that setter methods make objects of that class amenable to reconfiguration or re-injection later. Management through?JMX MBeans?is therefore a compelling use case for setter injection.

Use the DI style that makes the most sense for a particular class. Sometimes, when dealing with third-party classes for which you do not have the source, the choice is made for you. For example, if a third-party class does not expose any setter methods, then constructor injection may be the only available form of DI.

?最終要的是這句:

以下解釋來自:https://www.cnblogs.com/joemsu/p/7688307.html#_caption_2

The Spring team generally advocates constructor injection as it enables one to implement application components as?immutable objects?and to ensure that required dependencies are not?null. Furthermore constructor-injected components are always returned to client (calling) code in a fully initialized state.

? 咳咳,再來簡單的翻譯一下:這個構造器注入的方式啊,能夠保證注入的組件不可變,并且確保需要的依賴不為空。此外,構造器注入的依賴總是能夠在返回客戶端(組件)代碼的時候保證完全初始化的狀態
?

下面來簡單的解釋一下:

  • 依賴不可變:其實說的就是final關鍵字
  • 依賴不為空(省去了我們對其檢查):當要實例化FooController的時候,由于自己實現了有參數的構造函數,所以不會調用默認構造函數,那么就需要Spring容器傳入所需要的參數,所以就兩種情況:1、有該類型的參數->傳入,OK 。2:無該類型的參數->報錯。所以保證不會為空,Spring總不至于傳一個null進去吧 😦
  • 完全初始化的狀態:這個可以跟上面的依賴不為空結合起來,向構造器傳參之前,要確保注入的內容不為空,那么肯定要調用依賴組件的構造方法完成實例化。而在Java類加載實例化的過程中,構造方法是最后一步(之前如果有父類先初始化父類,然后自己的成員變量,最后才是構造方法,這里不詳細展開。)。所以返回來的都是初始化之后的狀態。

結論


應盡量避免 Field 注入。推薦使用構造函數或方法來注入依賴項。兩者各有利弊,其用法取決于具體情況。但是,由于這些方法可以混合使用,所以這不是非必須選擇一種,可以將 Setter 和構造函數注入合并到一個類中。構造函數更適合于強制依賴項和以不變性為目標的情況。對于可選的依賴項,Setter 更好。

然后我在另一篇博客中也讀到,使用@Resource替代@Autowired就沒有這個提示了.....

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

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

相關文章

分布式 - 消息隊列Kafka:Kafka消費者和消費者組

文章目錄 1. Kafka 消費者是什么?2. Kafka 消費者組的概念?3. Kafka 消費者和消費者組有什么關系?4. Kafka 多個消費者如何同時消費一個分區? 1. Kafka 消費者是什么? 消費者負責訂閱Kafka中的主題,并且從…

【數據結構OJ題】反轉鏈表

原題鏈接:https://leetcode.cn/problems/reverse-linked-list/description/ 目錄 1. 題目描述 2. 思路分析 3. 代碼實現 1. 題目描述 2. 思路分析 方法一:三指針翻轉法 使用三個結構體指針n1,n2,n3,原地修改結點…

VSCode如何設置高亮

一、概述 本文主要介紹在 VSCode 看代碼時,怎樣使某個單詞高亮顯示,主要通過以下三步實現: 安裝 highlight-words 插件 配置 highlight-words 插件 設置高亮快捷鍵F8 工作是嵌入式開發的,代碼主要是C/C的,之前一直用…

【Linux】高級IO

目錄 IO的基本概念 釣魚五人組 五種IO模型 高級IO重要概念 同步通信 VS 異步通信 阻塞 VS 非阻塞 其他高級IO 阻塞IO 非阻塞IO IO的基本概念 什么是IO? I/O(input/output)也就是輸入和輸出,在著名的馮諾依曼體系結構當中…

ROS學習筆記(三)---好用的終端Terminator

ROS學習筆記文章目錄 01. ROS學習筆記(一)—Linux安裝VScode 02. ROS學習筆記(二)—使用 VScode 開發 ROS 的Python程序(簡例) 一、Terminator是什么? 在前面的學習中,為了運行hello.py我是在vscode頻繁的點擊運行窗口的“”號…

智谷星圖趙俊:讓人才和區塊鏈產業“雙向奔赴”丨對話MVP

區塊鏈產業需要什么樣的人才?趙俊很有發言權。 趙俊是北京智谷星圖科技有限公司的技術總監,也是FISCO BCOS官方認證講師。他2017年接觸區塊鏈,隨后選擇人才培育領域深耕。“為區塊鏈行業引進更多人才這件事很有價值,跟我的職業理…

菜單和內容滾動的聯動原理及代碼

之前寫代碼有個需求:左側是一個菜單,右邊是內容,點擊左側菜單右邊內容滾動到對應位置,右邊內容滾動到某位置時,左側菜單也會選中對應的菜單項。UI如下:這是大多網站的移動端都會有的需求。 解決方案一&…

高憶管理:什么是一碼通?有什么好處?

在經過券商開戶后,除了其間的財物賬戶、滬深股賬戶外,還有一個一碼通賬戶,什么是一碼通?它有什么好處?關于這些,高憶管理為大家預備了以下參閱內容。 什么是一碼通? 一碼通賬戶,一般…

CSDN編程題-每日一練(2023-08-15)

CSDN編程題-每日一練(2023-08-15) 一、題目名稱:新型美麗數列二、題目名稱:會議安排三、題目名稱:小豚鼠搬家一、題目名稱:新型美麗數列 時間限制:1000ms內存限制:256M 題目描述: 定義美麗數列A: 1. 數列中相鄰的數越是靠內相對大小加一,a[2]=a[1]+1,a[n-2]=a[n-1]+1…

【C語言】小游戲-掃雷(清屏+遞歸展開+標記)

大家好&#xff0c;我是深魚~ 目錄 一、游戲介紹 二、文件分裝 三、代碼實現步驟 1.制作簡易游戲菜單 2. 初始化棋盤(11*11) 3.打印棋盤(9*9) 4.布置雷 5.計算(x,y)周圍8個坐標的和 6.排查雷 <1>清屏后打印棋盤 <2>遞歸展開 <3>標記雷 四、完整代…

視頻監控有哪些存儲方式?安防監控應該如何選擇存儲模式?

視頻監控系統涉及到大量的視頻數據&#xff0c;需要對這些數據進行存儲&#xff0c;以備日后查看或備份。視頻監控的存儲需求需要根據場所的實際情況進行選擇&#xff0c;以保證監控數據的有效存儲和日后的調閱、回溯。 當前視頻監控的存儲方式&#xff0c;通常有以下幾種&…

Golang協程,通道詳解

進程、線程以及并行、并發 關于進程和線程 進程&#xff08;Process&#xff09;就是程序在操作系統中的一次執行過程&#xff0c;是系統進行資源分配和調度的基 本單位&#xff0c;進程是一個動態概念&#xff0c;是程序在執行過程中分配和管理資源的基本單位&#xff0c;每…

【BASH】回顧與知識點梳理(二十三)

【BASH】回顧與知識點梳理 二十三 二十三. Linux 賬號管理&#xff08;二&#xff09;23.1 賬號管理新增與移除使用者&#xff1a; useradd, 相關配置文件, passwd, usermod, userdelusermoduserdel 23.2 用戶功能&#xff08;普通用戶可使用&#xff09;idfingerchfnchsh 23.3…

【數據庫系統】--【2】DBMS架構

DBMS架構 01DBMS架構概述02 DBMS的物理架構03 DBMS的運行和數據架構DBMS的運行架構DBMS的數據架構PostgreSQL的體系結構RMDB的運行架構 04DBMS的邏輯和開發架構DBMS的層次結構DBMS的開發架構DBMS的代碼架構 05小結 01DBMS架構概述 02 DBMS的物理架構 數據庫系統的體系結構 數據…

騰訊Perfdog支持Windows PC端體驗性能測試

一、背景 最近在做抖音的小玩法&#xff0c;其基于unity引擎&#xff0c;然后掛載到直播伴侶。以及Perfdog近期也支持了Windows的測試&#xff0c;所以做一個體驗測試。 二、如何做 查看PC端的支持&#xff0c;目前是beat版本 選擇或搜索自己需要的對應的程序&#xff0c;如…

python實現文本相似度排名計算

項目中&#xff0c;客戶突然提出需要根據一份企業名單查找對應的內部系統用戶信息&#xff0c;然后根據直接的企業社會統一信用號和企業名稱進行匹配&#xff0c;發現匹配率只有2.86%&#xff0c;低得可憐。所以根據客戶的要求&#xff0c;需要將匹配率提高到70-80%左右&#x…

vue2+百度地圖web端開發

在Vue 2中開發百度地圖Web端應用&#xff0c;你可以使用百度地圖JavaScript API來實現地圖功能。以下是一個簡單的示例&#xff1a; 簡單的示例&#xff1a; 首先&#xff0c;在你的Vue項目中安裝vue-baidu-map插件&#xff1a; npm install vue-baidu-map --save在你的Vue組…

大數據Flink(五十九):Flink on Yarn的三種部署方式介紹以及注意

文章目錄 Flink on Yarn的三種部署方式介紹以及注意 一、Pre-Job 模式部署作業

對任意類型數都可以排序的函數:qsort函數

之前我們學習過冒泡排序&#xff1a; int main() {int arr[] { 9,7,8,6,5,4,3,2,1,0 };int sz sizeof(arr)/sizeof(arr[0]);int i 0;for (i 0; i < sz-1; i) {int j 0;for (j 0; j < sz-1-i; j) {if (arr[j] > arr[j 1]){int temp 0;temp arr[j];arr[j] ar…

接口測試及接口抓包常用的測試工具

接口 接口測試是測試系統組件間接口的一種測試。接口測試主要用于檢測外部系統與系統之間以及內部各個子系統之間的交互點。測試的重點是要檢查數據的交換&#xff0c;傳遞和控制管理過程&#xff0c;以及系統間的相互邏輯依賴關系等。 接口測試的重要性 是節省時間前后端不…