【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…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
