【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…...
Claude Code源码分析之提示词工程
每天免费领 1亿 Token,白嫖DeepSeek、GLM、MiniMax、Kimi等大模型! 在开发大模型应用的时候,管理系统提示词(System Prompt)往往是个让人头大的工程难题。要是只用简单的字符串拼接,随着活儿越接越多&#…...
Go语言的Kubernetes编排实践
Go语言的Kubernetes编排实践 1. Kubernetes简介 Kubernetes(简称K8s)是一个开源的容器编排平台,用于自动化容器的部署、扩展和管理。它提供了强大的容器编排能力,使应用程序能够在分布式环境中高效运行。 1.1 Kubernetes的核心概念…...
云原生环境中的边缘计算应用
云原生环境中的边缘计算应用 引言:边缘计算的崛起 哥们,别整那些花里胡哨的!作为一个前端开发兼摇滚鼓手,我最烦的就是延迟。在云原生时代,边缘计算让我们离用户更近,减少延迟。今天,我就给你们…...
JavaScript 如何捕获异常:从基础到进阶的完整指南
在 JavaScript 开发中,异常处理是保证代码健壮性的关键环节。无论是用户输入错误、网络请求失败,还是第三方库的意外行为,都可能导致程序崩溃或行为异常。如何优雅地捕获异常并提供合理的回退方案,是每个开发者必须掌握的技能。 本…...
多年研究图像增强算法,包括但不限于:retinex,gamma,clahe,滤波算法。如果有需要此方面的需要,可以找我哦,理论算法打包带走
多年研究图像增强算法,包括但不限于:retinex,gamma,clahe,滤波算法。如果有需要此方面的需要,可以找我哦,理论算法打包带走...
《Qt/UI美化实战课程》| 第五章 自定义仪表盘(美观/高度定制/自适应大小)| 9. 实现仪表盘(1) 新建项目、界面布局
1. 从零搭建Qt仪表盘项目框架 第一次接触Qt自定义控件开发时,我被仪表盘这种既美观又实用的组件深深吸引。记得当时为了做一个工业监控项目,需要展示温度、压力等实时数据,传统的进度条和数字显示实在太枯燥。下面我就带大家从最基础的项目搭…...
告别源码编译:在ARM服务器(如华为云鲲鹏)上快速部署GCC的三种‘懒人’方法
在ARM服务器上高效部署GCC的三大实战方案 当你在华为云鲲鹏或AWS Graviton等ARM架构服务器上搭建开发环境时,是否曾被繁琐的GCC源码编译过程困扰?本文将分享三种经过实战验证的快速部署方案,帮助你在aarch64架构的Linux系统中,用最…...
知识管理新范式:dedao-dl实现得到课程资源备份与永久归档指南
知识管理新范式:dedao-dl实现得到课程资源备份与永久归档指南 【免费下载链接】dedao-dl 得到 APP 课程下载工具,可在终端查看文章内容,可生成 PDF,音频文件,markdown 文稿,可下载电子书。 项目地址: htt…...
用快马平台快速构建cc switch游戏交互原型,三步实现状态切换demo
今天想和大家分享一个快速验证游戏交互设计的小技巧——用InsCode(快马)平台三步搞定角色状态切换原型。最近在做一个横版动作游戏,需要实现类似《空洞骑士》那种技能切换系统,传统开发流程至少要花半天搭环境写基础代码,现在用这个平台十分钟…...
三阶掌握ST7789显示屏驱动:从基础控制到高级应用的嵌入式实战指南
三阶掌握ST7789显示屏驱动:从基础控制到高级应用的嵌入式实战指南 【免费下载链接】st7789py_mpy 项目地址: https://gitcode.com/gh_mirrors/st/st7789py_mpy ST7789py_mpy是一款专为嵌入式系统设计的高性能MicroPython显示屏驱动库,完整支持ST…...
