SpringBoot中定義了Bean,但是為什么依賴注入的時候注入不了

背景:

擴展RedisTemplate的實現的時候寫了這樣一段代碼:

public class BusinessRedisTemplate extends RedisTemplate<String, String> {private final String prefix = "business";public BusinessRedisTemplate (RedisConnectionFactory connectionFactory) {setConnectionFactory(connectionFactory);}public BusinessRedisTemplate (RedisConnectionFactory connectionFactory) {setConnectionFactory(connectionFactory);}}

BusinessRedisTemplate 繼承了RedisTemplate,并重寫了convertAndSend()方法,邏輯比較簡單,統一給消息加個前綴,實際工作中更復雜一點,BusinessRedisTemplate 要生效就需要把它定義為Bean,所以有了如下Bean定義代碼:

@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){return new BusinessRedisTemplate (redisConnectionFactory);
}

然后在Service中注入它:

@Autowired
private BusinessRedisTemplate  redisTemplate;

然后啟動SpringBoot,竟然報錯了:

a bean of type 'com.business.BusinessRedisTemplate ' that could not be found.

說找不到BusinessRedisTemplate 這個類型的Bean,可是我明明定義了呀…,為什么會這樣?關鍵是我如果把屬性類型改為RedisTemplate就不報錯了,也就是這樣:

@Autowired
private RedisTemplate redisTemplate;

而且我debug了確實找到就是BusinessRedisTemplate 對象,那為什么上面那么寫就找不到Bean呢?情況就是這么個情況,不知道各位大佬想到原因了沒,暫時沒想到的,那就聽我來給大家分析分析。

首先,拋一個問題給大家:Spring在根據屬性進行依賴注入時,所需的Bean對象是否已經存在了?

答案是不一定,得看Bean的創建順序,比如順序是A—>B,A里面依賴了B,就算A和B都是非懶加載的單例Bean,Spring也會按順序進行創建,那么在創建A時就會進行依賴注入,而這個時候B對象是不存在的,所以A在進行依賴注入時需要判斷:Spring容器中有沒有B類型的Bean對象,如果沒有則判斷有沒有B類型的Bean定義,如果有Bean定義,那就此時此刻根據Bean定義把B對象創建出來,如果沒有,則報上述根據類型找不到Bean的錯誤。

回到我們的場景,其實類似,原因就是在創建Service的Bean對象時會針對屬性進行依賴注入,會根據BusinessRedisTemplate 類型去Spring容器找Bean對象,不過這時Spring容器中是沒有BusinessRedisTemplate 類型的Bean對象的,所以Spring會去找BusinessRedisTemplate 類型的Bean定義,那為什么找不到BusinessRedisTemplate 類型的Bean定義呢?我們再來看看我們定義Bean的方式:

@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){return new BusinessRedisTemplate (redisConnectionFactory);
}

這個Bean的類型到底是RedisTemplate,還是BusinessRedisTemplate 呢?不一樣嗎?它兩不是父子關系嗎?

來來來,重點來了,當Spring解析@Bean注解時,也就是在生成Bean定義時,會把方法的返回值類型RedisTemplate當做Bean類型,而不會把方法中真正返回的對象類型當做Bean類型,因為在解析@Bean注解時并不會真正執行該方法,所以這個Bean的類型一開始只能是RedisTemplate,只有真正執行了該方法之后才知道它具體的類型是BusinessRedisTemplate 。

所以Service中在進行依賴注入時,只能找到RedisTemplate類型的Bean,而找不到BusinessRedisTemplate 類型的Bean,除非!在進行本次依賴注入之前,BusinessRedisTemplate 這個Bean對象已經被創建出來了,這樣在進行依賴注入的時候,就能根據RedisTemplate類型找到BusinessRedisTemplate 這個Bean對象了(根據父類找到子類對象)。

所以,我們再來看一下依賴注入的代碼:

@Autowired
private BusinessRedisTemplate redisTemplate;

如果屬性類型是BusinessRedisTemplate ,那么就有可能根據BusinessRedisTemplate 類型即找不到Bean對象,也找不到Bean定義,從而報錯。

而如果改成:

@Autowired
private RedisTemplate redisTemplate;

就可以了,因為就算根據RedisTemplate類型找不到Bean對象,也能根據RedisTemplate類型找到Bean定義,最終也能根據Bean定義創建出來BusinessRedisTemplate 對象完成依賴注入。

當然,最好的方式是改Bean的定義:

@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){return new BusinessRedisTemplate (redisConnectionFactory);
}

改為:

@Bean
public BusinessRedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){return new BusinessRedisTemplate (redisConnectionFactory);
}

這樣不管是根據BusinessRedisTemplate 類型找Bean定義,還是根據RedisTemplate類型找Bean定義,都能找到。

也許有讀者會想到,改成@Resource行不行,只能說可能行,也可能不行,因為@Resource會先根據名字找Bean,找到了自然沒問題,但是如果找不到仍然會再根據類型找Bean,最終也可能進入本文所分析的場景中。

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

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

相關文章

十八、圖像像素類型轉換和歸一化操作

項目功能實現&#xff1a;對一張圖像進行類型轉換和歸一化操作 按照之前的博文結構來&#xff0c;這里就不在贅述了 一、頭文件 norm.h #pragma once#include<opencv2/opencv.hpp>using namespace cv;class NORM { public:void norm(Mat& image); };#pragma once二…

智慧公廁是什么?智慧公廁是構建智慧城市的環境衛生基石

隨著城市化進程的不斷加速&#xff0c;城市人口密度和流動性也逐漸增大&#xff0c;對城市公共設施的需求與日俱增。而在這些公共設施中&#xff0c;公廁作為城市基礎設施中不可或缺的一環&#xff0c;對城市的環境衛生和市民生活質量起著舉足輕重的作用。如何提高公廁的管理效…

android studio 中使用kotlin語言 直接操作布局id

android studio 中使用kotlin語言 直接操作布局id 需要在 build.gradle 文件 引入 apply plugin: kotlin-android apply plugin: kotlin-android-extensions&#xff08;會自動生成&#xff0c;可忽略&#xff09;然后在 Activity 文件中 引入 對應的 layout 文件 如&#xff…

MacOs 圍爐夜話

文章目錄 一、安裝 Mac 一、安裝 Mac macOS是一套由蘋果開發的運行于Macintosh系列電腦上的操作系統。macOS是首個在商用領域成功的圖形用戶界面操作系統。 VM虛擬機怎么安裝mac os&#xff1f;&#xff08;全教程&#xff09; 虛擬機&#xff1a;VMware Workstation 17 pro W…

新書推薦:《分布式商業生態戰略:未來數字商業新邏輯與企業數字化轉型新策略》

近兩年&#xff0c;商業經濟環境的不確定性越來越明顯&#xff0c;市場經濟受到疫情、技術、政策等多方因素影響越來越難以預測&#xff0c;黑天鵝事件時有發生。在國內外經濟方面&#xff0c;國際的地緣政治對商業經濟產生著重大的影響&#xff0c;例如供應鏈中斷&#xff0c;…

Shopify配置項過多如何在代碼層面簡化輸出內容

在處理 Shopify 的配置項過多的情況下&#xff0c;可以通過在代碼層面簡化輸出內容來提高效率和可維護性。以下是一些方法&#xff1a; 1. 使用循環和條件語句 使用循環和條件語句來動態生成和輸出內容。通過遍歷配置項的列表或對象&#xff0c;可以根據條件決定是否輸出相應的…

Backend - Django SimpleUI(美化 Django Admin )

目錄 一、作用 二、安裝 & 配置 &#xff08;一&#xff09;安裝依賴 &#xff08;二&#xff09;配置 &#xff08;三&#xff09;運行 三、基礎設定 &#xff08;一&#xff09;創建用戶 &#xff08;二&#xff09;設置標題 &#xff08;三&#xff09;設置登錄…

代理模式筆記

代理模式 代理模式代理模式的應用場景先理解什么是代理&#xff0c;再理解動靜態舉例舉例所用代碼 動靜態的區別靜態代理動態代理 動態代理的優點代理模式與裝飾者模式的區別 代理模式 代理模式在設計模式中是7種結構型模式中的一種&#xff0c;而代理模式有分動態代理&#x…

rabbitmq知識梳理

一.WorkQueues模型 Work queues&#xff0c;任務模型。簡單來說就是讓多個消費者綁定到一個隊列&#xff0c;共同消費隊列中的消息。 當消息處理比較耗時的時候&#xff0c;可能生產消息的速度會遠遠大于消息的消費速度。長此以往&#xff0c;消息就會堆積越來越多&#xff0c…

四、矩陣的分類

目錄 1、相等矩陣 2、同形矩陣 3、方陣&#xff1a; 4、負矩陣、上三角矩陣、下三角矩陣&#xff1a; 5、對角矩陣&#xff1a;是方陣 ?編輯7、單位矩陣&#xff1a;常常用 E或I 來表示。它是一個方陣 8、零矩陣&#xff1a; 9、對稱矩陣&#xff1a;方陣 1、相等矩陣 …

openEuler安裝MySQL客戶端、openEuler安裝MySQL-client、openEuler部署MySQL-client

MySQL客戶端下載鏈接&#xff1a;https://downloads.mysql.com/archives/community/ mysql-community-client-5.7.30-1.el7.x86_64.rpm mysql-community-common-5.7.30-1.el7.x86_64.rpm mysql-community-libs-5.7.30-1.el7.x86_64.rpm 3個必選 8.0.22以上的版本是4個&…

HDFS中常用的Shell命令 全面且詳細

HDFS中常用的Shell命令目錄 一、ls命令 二、mkdir 命令 三、put命令 四、get命令 五、mv命令 六、rm命令 七、cp命令 八、cat命令 前言 安裝好hadoop環境之后&#xff0c;可以執行hdfs相關的shell命令對hdfs文件系統進行操作&#xff0c;比如文件的創建、刪除、修改文…

【FPGA】VHDL:小型出勤系統設計

附源代碼&#xff0c;一定能實現&#xff01; 目錄 EDA設計練習題&#xff1a; 實驗要求如下&#xff1a; 思路分析&#xff1a; 代碼 99進制計數器 碼轉換 頂層文件 特別注意 測試 編譯通過 結果展示 RTL視圖 技術映射視圖 軟件&#xff1a;Quartus II 13.0 (64…

BERT學習筆記

論文&#xff1a;《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》&#xff0c;2019 代碼&#xff1a;[tensorflow]&#xff0c;[pytorch] 來源&#xff1a;李沐精度BERT 0、摘要 與之前模型的區別&#xff1a; GPT考慮的是一個單向…

公司中常用的系統有哪些--制造業篇

摘要 本系列博客主要介紹不同行業中使用的常見系統&#xff0c;本文介紹在制造業或是智能制造方向的常見系統。 智能制造發展史 1973年美國約瑟夫哈林頓&#xff08;Joseph Harrington&#xff09;博士在《Computer Integrated Manufacturing》一書中首次提出 CIM&#xff08…

C# 本地方法和lambda實現

概念&#xff1a; 本地函數是一種嵌套在另一成員中的類型的方法。 僅能從其包含成員中調用它們。 下面是本地方法最簡單的一個demo: public static int Show(){int c NewMethod(); return c;static int NewMethod(){#region 測試int a 3;int b 9;int c a b;#endregionre…

python opencv實現車牌識別

目錄 一:實現步驟: 二:實現車牌檢測 一:實現步驟: 使用Python和OpenCV實現車牌識別的步驟大致可以分為以下兩部分: 車牌檢測: 讀取需要進行車牌識別的圖片。 對圖像進行灰度化處理,可能還包括高斯模糊和灰度拉伸。 進行開運算,消除圖像中的噪聲。 將灰度拉伸后的圖…

培養納稅籌劃思維方式,企業稅務籌劃實務操作

一、教程描述 本套稅務籌劃教程&#xff0c;大小447.87M&#xff0c;共有6個文件。 二、教程目錄 前言.mp4 培養納稅籌劃思維方式.mp4 增值稅的稅務籌劃.mp4 企業所得稅的稅務籌劃.mp4 個人所得稅的稅務籌劃.mp4 企業稅務籌劃實務操作&#xff08;課件&#xff09;.pdf…

MDST150-16-ASEMI三相可控整流模塊MDST150-16

編輯&#xff1a;ll MDST150-16-ASEMI三相可控整流模塊MDST150-16 型號&#xff1a;MDST150-16 品牌&#xff1a;ASEMI 正向電流&#xff08;Id&#xff09;&#xff1a;150A 反向耐壓&#xff08;VRRM&#xff09;&#xff1a;1600V 正向浪涌電流&#xff1a;1200A 正…

大數據揭秘:Hadoop短視頻流量分析實戰

??計算機編程指導師 ??個人介紹&#xff1a;自己非常喜歡研究技術問題&#xff01;專業做Java、Python、微信小程序、安卓、大數據、爬蟲、Golang、大屏等實戰項目。 ??實戰項目&#xff1a;有源碼或者技術上的問題歡迎在評論區一起討論交流&#xff01; ?? Java實戰 |…