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.mzph.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实战 |…