【Spring进阶系列丨第五篇】详解Spring中的依赖注入

文章目录
- 一、说明
- 二、构造函数注入
- 2.1、方式一【index索引方式】
- 2.1.1、定义Bean
- 2.1.2、主配置文件中配置Bean
- 2.1.3、测试
- 2.2、方式二【index+type组合方式】
- 2.2.1、定义Bean
- 2.2.2、主配置文件配置Bean
- 2.2.3、测试
- 2.2.4、解决方案
- 2.3、方式三【name方式】
- 2.3.1、定义Bean
- 2.3.2、主配置文件配置Bean
- 2.3.3、测试
- 2.4、补充细节
- 2.4.1、定义Bean
- 2.4.2、主配置文件配置Bean
- 2.4.3、测试
- 2.4.4、解决方案
- 2.5、总结
- 三、set方法注入
- 3.1、定义Bean
- 3.2、主配置文件配置Bean
- 3.3、测试
- 3.4、总结
- 四、复杂类型的注入
- 4.1、注入数组类型【array】
- 4.1.1、定义Bean
- 4.1.2、主配置文件配置Bean
- 4.2、注入List类型【list】
- 4.2.1、定义Bean
- 4.2.2、主配置文件配置Bean
- 4.3、注入Set类型【set】
- 4.3.1、定义Bean
- 4.3.2、主配置文件配置Bean
- 4.4、注入Map类型【Map】
- 4.4.1、定义Bean
- 4.4.2、主配置文件配置Bean
- 4.5、注入Properties类型
- 4.5.1、定义Bean
- 4.5.2、主配置文件配置Bean
- 4.6、总结
- 好书推荐
- 送书活动
一、说明
-
全称
Dependency Injection(DI)
-
与IoC的关系
IoC和DI其实说的是一个意思,可以这么说:IoC是一种思想,DI是对这种思想的一种具体实现
- 依赖关系的管理
以后都交给spring来维护,在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明。
-
依赖关系的维护
称之为依赖注入。
-
能注入的数据:有三类
基本类型和String。
其他bean类型(在配置文件中或者注解配置过的bean)
复杂类型/集合类型
-
注入的方式:有三种
第一种:使用构造函数提供
第二种:使用set方法提供
第三种:使用注解提供(参考第七章节)
二、构造函数注入
2.1、方式一【index索引方式】
2.1.1、定义Bean
public class Person {private Integer id;private String name; // 姓名private Integer age; // 年龄private Double weight; // 体重public Person(Integer id, String name, Integer age) {this.id = id;this.name = name;this.age = age;}
}
2.1.2、主配置文件中配置Bean
<beans> <bean id="person" class="cn.bdqn.Person"><constructor-arg index="0" value="1" /><constructor-arg index="1" value="王浩"/><constructor-arg index="2" value="20"/></bean>
</beans>
2.1.3、测试
@Test
public void testPerson() throws Exception{// 1、读取主配置文件信息,获取核心容器对象ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");Person person = (Person) ac.getBean("person");System.out.println(person); // Person{id=1, name='王浩', age=20}
}
2.2、方式二【index+type组合方式】
说明:案例1采用的index索引的方式实现注入,就以目前案例来说是完全没问题的,但是如果Bean中存在下面情况,可能就不怎么适用了。
需求:我现在要创建Person类的对象,调用Person(Integer id, String name, Double weight)构造方法
2.2.1、定义Bean
说明:为Person类中的weight属性初始化,并专门为其添加构造方法
public class Person {private Integer id;private String name; // 姓名private Integer age; // 年龄private Double weight; // 体重public Person(Integer id, String name, Integer age) {this.id = id;this.name = name;this.age = age;}// 专门为weight属性定义的构造方法public Person(Integer id, String name, Double weight) {this.id = id;this.name = name;this.weight = weight;}
}
2.2.2、主配置文件配置Bean
<beans> <bean id="person" class="cn.bdqn.Person"><constructor-arg index="0" value="1" /><constructor-arg index="1" value="王浩"/><constructor-arg index="2" value="180"/></bean>
</beans>
2.2.3、测试
@Test
public void testPerson() throws Exception{// 1、读取主配置文件信息,获取核心容器对象ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");Person person = (Person) ac.getBean("person");System.out.println(person); // Person{id=1, name='王浩', age=180}
}
经过测试发现,并不满足我的需求,还是找的是public Person(Integer id, String name, Integer age)构造方法
2.2.4、解决方案
通过type明确指定类型。
<bean><bean id="person" class="cn.bdqn.Person"><constructor-arg index="0" type="java.lang.Integer" value="1" /><constructor-arg index="1" type="java.lang.String" value="王浩"/><constructor-arg index="2" type="java.lang.Double" value="180"/></bean>
</bean>
2.3、方式三【name方式】
前两种方式通过index+type的确可以解决问题,但是总是觉得还是有些麻烦,能否有更加简单的方式呢?就是直接采用参数名的方式更易于阅读和使用。
2.3.1、定义Bean
Bean的定义同2.2.1。
2.3.2、主配置文件配置Bean
<beans><bean id="person" class="cn.bdqn.Person"><constructor-arg name="id" value="2"/><constructor-arg name="name" value="史周冲"/><constructor-arg name="age" value="3"/></bean>
</beans>
2.3.3、测试
@Test
public void testPerson() throws Exception{// 1、读取主配置文件信息,获取核心容器对象ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");Person person = (Person) ac.getBean("person");System.out.println(person); // Person{id=1, name='王浩', age=3}
}
2.4、补充细节
2.4.1、定义Bean
public class Person {private Integer id;private String name; // 姓名private Date birthday; // 出生日期public Person(Integer id, String name, Date birthday) {this.id = id;this.name = name;this.birthday = birthday;}
}
2.4.2、主配置文件配置Bean
<beans><bean id="person" class="cn.bdqn.Person"><constructor-arg name="id" value="2"/><constructor-arg name="name" value="史周冲"/><constructor-arg name="birthday" value="2019-09-09" /></bean>
</beans>
2.4.3、测试
测试后发现程序报错,原因在于:期望需要一个Date类型,而你现在传了一个字符串,数据类型不匹配。
Unsatisfied dependency expressed through constructor parameter 2: Could not convert argument value of type [java.lang.String] to required type [java.util.Date]
2.4.4、解决方案
<beans><bean id="person" class="cn.bdqn.Person"><constructor-arg name="id" value="2"/><constructor-arg name="name" value="史周冲"/><!-- 注意:用了ref属性--><constructor-arg name="birthday" ref="currentDate"/></bean><!-- 定义日期Bean,Spring就会帮助我们new一个Date对象--><bean id="currentDate" class="java.util.Date"/>
</beans>
2.5、总结
-
使用的标签:
constructor-arg
-
标签出现的位置:
bean标签的内部
-
标签中的属性:
type:用于指定要注入的数据的数据类型。
index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值,索引的位置是从0开始。
name:用于指定给构造函数中指定名称的参数赋值。
value:用于提供基本类型和String类型的数据。
ref:引用,用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象。
-
优势:
假设我们需要创建一个对象时,需要明确初始化一些数据,那么这种方式显然是很好的。因为通过构造函数创建对象时候,如果不指定具体的参数是无法把对象创建成功的。可以起到一个约束的作用。
-
劣势:
改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
三、set方法注入
3.1、定义Bean
public class User {private String name;private Date born;public void setName(String name) {this.name = name;}public void setBorn(Date born) {this.born = born;}
}
说明:set注入方式不必生成get方法
3.2、主配置文件配置Bean
<bean id="currentDate" class="java.util.Date"/><bean id="user" class="cn.bdqn.User"><property name="name" value="宋炜烨"/><property name="born" ref="currentDate"/>
</bean>
3.3、测试
@Test
public void testUser() throws Exception{// 1、读取主配置文件信息,获取核心容器对象ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");User user = (User) ac.getBean("user");System.out.println(user); // User{name='宋炜烨', born=Thu Nov 14 22:29:11 CST 2019}
}
3.4、总结
-
涉及的标签
property
-
出现的位置
bean标签的内部
-
标签的属性
name:用于指定注入时所调用的set方法名称。
value:用于提供基本类型和String类型的数据。
ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象。
-
优势
创建对象时没有明确的限制,可以直接使用默认构造函数。
-
劣势
如果有某个成员属性必须有值,则有可能再使用该对象的时候并没有通过set方法注入值,可能拿到为空的值。
四、复杂类型的注入
4.1、注入数组类型【array】
4.1.1、定义Bean
public class Cat {private String[] arrs;public void setArrs(String[] arrs) {this.arrs = arrs;}
}
4.1.2、主配置文件配置Bean
<beans><bean id="cat" class="cn.bdqn.Cat"><property name="arrs"><array><value>崔灿</value><value>时贝妮</value></array></property></bean>
</beans>
4.2、注入List类型【list】
4.2.1、定义Bean
public class Cat {private List<String> arrList;public void setArrList(List<String> arrList) {this.arrList = arrList;}
}
4.2.2、主配置文件配置Bean
<beans><bean id="cat" class="cn.bdqn.Cat"><property name="arrList"><list><value>乔峰</value><value>马夫人</value></list></property></bean>
</beans>
4.3、注入Set类型【set】
4.3.1、定义Bean
public class Cat {private Set<String> arrSet;public void setArrSet(Set<String> arrSet) {this.arrSet = arrSet;}
}
4.3.2、主配置文件配置Bean
<beans><bean id="cat" class="cn.bdqn.Cat"><property name="arrSet"><set><value>段誉</value><value>鸠摩智</value></set></property></bean>
</beans>
4.4、注入Map类型【Map】
4.4.1、定义Bean
public class Cat {private Map<String,Object> arrMap;public void setArrMap(Map<String, Object> arrMap) {this.arrMap = arrMap;}
}
4.4.2、主配置文件配置Bean
<bean><property name="arrMap"><map><entry key="S001" value="彭依凝"/><entry key="S002" value="段康家"/><entry key="S003" value="王浩"/></map></property>
</bean>
4.5、注入Properties类型
4.5.1、定义Bean
public class Cat {private Properties props;public void setProps(Properties props) {this.props = props;}
}
4.5.2、主配置文件配置Bean
<bean id="cat" class="cn.bdqn.Cat"><property name="props"><props><prop key="A001">虚竹</prop><prop key="A002">扫地僧</prop></props></property>
</bean>
4.6、总结
-
用于给List结构集合注入的标签:
list、array、set
-
用于个Map结构集合注入的标签:
map 、props
-
总结
结构相同,标签可以互换
好书推荐

《Spring Batch权威指南》主要内容:
-
探索Spring Batch 4中的新特性。
-
使用Spring Batch项目在云环境中完成有限的批处理任务。
-
通过一些示例,理解z新的基于Java和Spring Boot的配置技术
-
掌握复杂场景和云环境中的批处理
-
开发能够运行在现代平台上的批处理应用
-
除了Spring Batch,使用Spring Portfolio的其他部分开发关键任务型批处理应用
购书链接:点此进入
送书活动
参与方式:点击进入参与 公平公正公开 人少好中奖!

相关文章:
【Spring进阶系列丨第五篇】详解Spring中的依赖注入
文章目录 一、说明二、构造函数注入2.1、方式一【index索引方式】2.1.1、定义Bean2.1.2、主配置文件中配置Bean2.1.3、测试 2.2、方式二【indextype组合方式】2.2.1、定义Bean2.2.2、主配置文件配置Bean2.2.3、测试2.2.4、解决方案 2.3、方式三【name方式】2.3.1、定义Bean2.3.…...
DAP数据集成与算法模型如何结合使用
企业信息化建设会越来越完善,越来越体系化,当今数据时代背景下更加强调、重视数据的价值,以数据说话,通过数据为企业提升渠道转化率、改善企业产品、实现精准运营,为企业打造自助模式的数据分析成果,以数据…...
大数据监控
HBase 监控 {name“RegionServer”,sub“Server”,} irate(hadoop_hbase_totalrequestcount[5m]) irate(hadoop_hbase_totalrequestcount{instanceName“hacluster4”}[2m]) https://blog.csdn.net/Samooyou/article/details/129275640 https://www.tencentcloud.com/zh/doc…...
【C语言】数据结构——小堆实例探究
💗个人主页💗 ⭐个人专栏——数据结构学习⭐ 💫点击关注🤩一起学习C语言💯💫 导读: 我们在前面学习了单链表和顺序表,以及栈和队列。 今天我们来学习小堆。 关注博主或是订阅专栏&a…...
Vue中比较两个JSON对象的差异
要在Vue.js中实现JSON数据的对比差异功能,你可以使用一些库来简化任务,比如diff-match-patch。以下是一个简单的例子,演示如何使用deep-diff库在Vue.js中比较两个JSON对象的差异: 首先,确保你的项目中已经安装了diff-m…...
前端知识库Html5和CSS3
1、常见的水平垂直居中实现方案 最简单的方案是flex布局 .container{display: flex;align-items: center;justify-content: center; }绝对定位配合margin:auto(一定要给.son宽高) .father {position: relative;height: 300px; } .son {position: absolute;top: 0;right: 0;b…...
智能优化算法应用:基于鸡群算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于鸡群算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于鸡群算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.鸡群算法4.实验参数设定5.算法结果6.参考文献7.MA…...
Apollo配置发布原理解析
📫作者简介:小明java问道之路,2022年度博客之星全国TOP3,专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化,文章内容兼具广度、深度、大厂技术方案,对待技术喜欢推理加验证,就职于…...
TrustGeo论文问题理解
1、网络空间测绘中,如何理解地标? 在网络空间测绘中,地标可以理解为在互联网空间中具有明显特征和稳定性的实体,它们可以作为网络空间的基准点,用于定位和标识其他网络实体。地标通常是在网络空间中具有较高价值和影响…...
子查询在SQL中的应用和实践
作者:CSDN-川川菜鸟 在SQL中,子查询是一种强大的工具,用于解决复杂的数据查询问题。本文将深入探讨子查询的概念、类型、规则,并通过具体案例展示其在实际应用中的用途。 文章目录 子查询概念子查询的类型子查询的规则实际案例分析…...
C# Socket通信从入门到精通(14)——多个异步UDP客户端C#代码实现
前言: 在之前的文章C# Socket通信从入门到精通(13)——单个异步UDP客户端C#代码实现我介绍了单个异步Udp客户端的c#代码实现,但是有的时候,我们需要连接多个服务器,并且对于每个服务器,我们都有一些比如异步发送、异步接收的操作,那么这时候我们使用之前单个异步Udp客…...
【教3妹学编程-算法题】需要添加的硬币的最小数量
3妹:2哥2哥,你有没有看到新闻, 有人中了2.2亿彩票大奖! 2哥 : 看到了,2.2亿啊, 一生一世也花不完。 3妹:为啥我就中不了呢,不开心呀不开心。 2哥 : 得了吧,你又不买彩票&…...
【异常解决】SpringBoot + Maven 在 idea 下启动报错 Unable to start embedded Tomcat(已解决)
Unable to start embedded Tomcat(已解决) 一、背景介绍二、原因分析2.1 网络上整理2.2 其他原因 三、解决方案 一、背景介绍 spring boot(v2.5.14) maven idea 启动项目 之前项目一直启动的好好的,都能正常运行。重启的时候突然就不能启…...
做题总结 707. 设计链表
做题总结 707. 设计链表 leetcode中单链表节点的默认定义我的尝试正确运行的代码(java) leetcode中单链表节点的默认定义 class ListNode {int val;ListNode next;//无参public ListNode() {}//有参:1public ListNode(int val) {this.val val;}//有参:…...
django实现--视图的使用
在 Django 中,视图是处理 Web 请求并返回 Web 响应的组件。Django 提供了两种主要类型的视图:基于函数的视图和基于类的视图。下面详细解释基于类的视图的实现方法、使用以及与基于函数的视图的异同。 基于类的视图的实现方法 继承 Django 的类视图基类…...
【dirty cred】fileManager [XXX]
前言 这应该不是个题,应该是佬为了测试 dirty cred 利用写的。但是环境有问题,测试最多只能向文件中写入 1024MB 的数据。所以竞争窗口太短了,但是似乎替换 credential obj 又是成功的了。感觉是环境的问题。 漏洞分析与利用 一次任意释放…...
线程按顺序循环执行
不瞒大家说,这是之前参加阿里一面的手写编程题,平时不刷题,这个当时花的时间比较多,虽然最后用了很喽比方法写出来了,自己还是很不满意。下面实话也是看了其他大佬的思路,今天重新练了下。 假设有3个线程,依次打印A、B、C,按顺序循环打印100次。 这个其实是线程通信,…...
C# 使用异步委托获取线程返回值
写在前面 异步委托主要用于解决 ThreadPool.QueueUserWorkItem 没有提供获取线程执行完成后的返回值问题。异步委托只能在.Net Framework 框架下使用,.Net Core中会报平台错误,而且使用Task.Result来获取返回值,可以达成同样的目的ÿ…...
生鲜蔬果展示预约小程序作用是什么
线下生鲜蔬果店非常多,对商家来说主要以同城生意为主,而在互联网电商的发展下,更多的商家会选择搭建私域商城进行多渠道的销售卖货和拓展,当然除了直接卖货外,还有产品纯展示或预约订购等需求。 但无论哪种模式&#…...
【C++】类与对象(下)
本文目录 1. 再谈构造函数1.1 构造函数体赋值1.2 初始化列表1.3 explicit关键字 2. static成员2.1 概念2.2 特性 3. 友元3.1 友元函数3.2 友元类 4. 内部类5. 匿名对象6. 拷贝对象时的一些编译器优化7. 再次理解类和对象 1. 再谈构造函数 1.1 构造函数体赋值 在创建对象时&am…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
