Spring DI简介及依赖注入方式和依赖注入类型
目录
一、什么是依赖注入
二、依赖注入方式
1. Setter注入
2. 构造方法注入
3. 自动注入
三、依赖注入类型
1. 注入bean类型
2. 注入基本数据类型
3. 注入List集合
4. 注入Set集合
5. 注入Map集合
6. 注入Properties对象
往期专栏&文章相关导读
1. Maven系列专栏文章
2. Mybatis系列专栏文章
3. Spring系列专栏文章
一、什么是依赖注入
依赖注入(Dependency Injection,简称DI),它是Spring控制反转思想的具体实现。
控制反转将对象的创建交给了Spring,但是对象中可能会依赖其他对象。比如service类中要有dao类的属性,我们称service依赖于dao。之前需要手动注入属性值,代码如下:
public interface StudentDao {
Student findById(int id);
}
public class StudentDaoImpl implements StudentDao{
@Override
public Student findById(int id) {
// 模拟根据id查询学生
return new Student(1,"程序员","北京");
}
}
public class StudentService {// service依赖dao,手动注入属性值,即手动维护依赖关系
private StudentDao studentDao = new StudentDaoImpl();
public Student findStudentById(int id){
return studentDao.findById(id);
}
}
此时,当StudentService的想要使用StudentDao的另一个实现类如StudentDaoImpl2时,则需要修改Java源码,造成代码的可维护性降低。
而使用Spring框架后,Spring管理Service对象与Dao对象,此时它能够为Service对象注入依赖的Dao属性值。这就是Spring的依赖注入。简单来说,控制反转是创建对象,依赖注入是为对象的属性赋值
二、依赖注入方式
1. Setter注入
被注入类编写属性的setter方法
public void setStudentDao(StudentDao studentDao){this.studentDao = studentDao;}
配置文件中,给需要注入属性值的 <bean> 中设置 <property>
<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"> </bean>
<bean id="studentService" class="com.itbaizhan.service.StudentService"><!--依赖注入--><!--name:对象的属性名 ref:容器中对象的id值--><property name="studentDao" ref="studentDao"></property>
</bean>
测试
新增测试方法
// 测试依赖注入@Testpublic void t6(){ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");StudentService service = (StudentService) ac.getBean("studentService");System.out.println(service.findStudentById(8));}
运行结果
OK,确实成功测试到了
2. 构造方法注入
被注入类编写有参的构造方法
public StudentService(StudentDao studentDao){this.studentDao = studentDao;}
给需要注入属性值的 <bean> 中设置 <constructor-arg>
<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean>
<bean id="studentService" class="com.itbaizhan.service.StudentService"><!-- 依赖注入 --><!-- name:对象的属性名 ref:配置文件中注入对象的id值 --><constructor-arg name="studentDao" ref="studentDao"></constructor-arg>
</bean>
测试结果:
OK,确实也是可以使用的
3. 自动注入
自动注入不需要在 <bean> 标签中添加其他标签注入属性值,而是自动从容器中找到相应的bean对象设置为属性值。
自动注入有两种配置方式:
- 全局配置:在 <beans> 中设置 default-autowire 属性可以定义所有bean对象的自动注入策略。
- 局部配置:在 <bean> 中设置 autowire 属性可以定义当前bean对象的自动注入策略。
autowire的取值如下:
- no:不会进行自动注入。
- default:全局配置default相当于no,局部配置default表示使用全局配置
- byName:在Spring容器中查找id与属性名相同的bean,并进行注入。需要提供set方法。
- byType:在Spring容器中查找类型与属性类型相同的bean,并进行注入。需要提供set方法。
- constructor:在Spring容器中查找id与属性名相同的bean,并进行注入。需要提供构造方法。
三、依赖注入类型
DI支持注入bean类型、基本数据类型和字符串、List集合、Set集合、Map集合、Properties对象类型等,他们的写法如下:
准备注入属性的类
package com.example.service;import com.example.dao.StudentDao;
import com.example.pojo.Student;import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;public class StudentService {// service依赖dao,手动注入属性值,即手动维护依赖关系//private StudentDao studentDao;// bean属性private StudentDao studentDao;// 字符串类型private String name;// 基本数据类型private int count;// 字符串List集合private List<String> students1;// 对象类型List集合private List<Student> nameList;// 字符串类型Set集合private Set<String> students2;// 字符串类型Map集合private Map<String, String> students3;// 对象类型map集合private Map<String,Student> studentMap;// Properties类型private Properties properties;public StudentService(){}public StudentService(StudentDao studentDao){this.studentDao = studentDao;}public Student findStudentById(int id){return studentDao.findById(id);}public void setStudentDao(StudentDao studentDao){this.studentDao = studentDao;}public StudentDao getStudentDao() {return studentDao;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getCount() {return count;}public void setCount(int count) {this.count = count;}public List<String> getStudents1() {return students1;}public void setStudents1(List<String> students1) {this.students1 = students1;}public Set<String> getStudents2() {return students2;}public void setStudents2(Set<String> students2) {this.students2 = students2;}public Map<String, String> getNames2() {return students3;}public void setNames2(Map<String, Student> names2) {this.studentMap = names2;}public Map<String, String> getStudents3() {return students3;}public void setStudents3(Map<String, String> students3) {this.students3 = students3;}public Properties getProperties() {return properties;}public void setProperties(Properties properties) {this.properties = properties;}public List<Student> getNameList() {return nameList;}public void setNameList(List<Student> nameList) {this.nameList = nameList;}@Overridepublic String toString() {return "StudentService[ " +"studentDao=" + studentDao +", name='" + name + '\'' +", count=" + count +", students1=" + students1 +", nameList=" + nameList +", students2=" + students2 +", students3=" + students3 +", studentMap=" + studentMap +", properties=" + properties +" ]";}
}
准备测试方法
// 测试注入类型@Testpublic void t7(){ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");StudentService service = (StudentService) ac.getBean("studentService");System.out.println(service);}
1. 注入bean类型
<!-- 注入bean类型 --><bean id="studentDao" class="com.example.dao.StudentDaoImpl1"/><!-- 写法1 --><bean id="studentService" class="com.example.service.StudentService"><property name="studentDao" ref="studentDao"/></bean><!-- 写法2 --><!--<bean id="studentService" class="com.example.service.StudentService"><property name="studentDao"><ref bean="studentDao"/></property></bean>-->
2. 注入基本数据类型
<!-- 注入基本数据类型 --><!-- 写法一 name:属性名 value:属性值 --><property name="name" value="程序员"/><!-- 写法二 name:属性名 value:属性值--><property name="count"><value>10</value></property>
3. 注入List集合
<!-- 注入List集合 --><!-- 简单的数据类型List集合 name:属性名 --><property name="students1" ><list><value>上海</value><value>广州</value></list></property><!-- 对象类型的List集合 name:属性名 --><property name="nameList"><list><bean class="com.example.pojo.Student"><property name="id" value="1"/><property name="name" value="几何心凉"/><property name="address" value="北京"/></bean><bean class="com.example.pojo.Student"><property name="id" value="2"/><property name="name" value="哈士奇"/><property name="address" value="上海"/></bean></list></property>
4. 注入Set集合
<!-- 注入Set集合 --><property name="students2"><set><value>深圳</value><value>北京</value></set></property>
5. 注入Map集合
<!-- 注入Map集合 --><property name="students3"><map><entry key="哈士奇" value="上海"/><entry key="几何心凉" value="北京"/></map></property><!-- 注入对象类型map类型 --><property name="names2"><map><entry key="student1" value-ref="s1"/><entry key="student2" value-ref="s2"/></map></property>
<bean id="s1" class="com.example.pojo.Student"><property name="id" value="1"/><property name="name" value="几何心凉"/><property name="address" value="北京"/></bean><bean id="s2" class="com.example.pojo.Student"><property name="id" value="2"/><property name="name" value="哈士奇"/><property name="address" value="上海"/></bean>
上面是用到的bean对象
6. 注入Properties对象
<!-- 注入properties --><property name="properties"><props><prop key="配置1">值1</prop><prop key="配置2">值2</prop></props></property>
运行测试方法测试一下
OK ,可以看到都是插入的了。
往期专栏&文章相关导读
大家如果对于本期内容有什么不了解的话也可以去看看往期的内容,下面列出了博主往期精心制作的Maven,Mybatis等专栏系列文章,走过路过不要错过哎!如果对您有所帮助的话就点点赞,收藏一下啪。其中Spring专栏有些正在更,所以无法查看,但是当博主全部更完之后就可以看啦。
1. Maven系列专栏文章
Maven系列专栏 | Maven工程开发 |
Maven聚合开发【实例详解---5555字】 |
2. Mybatis系列专栏文章
Mybatis系列专栏 | MyBatis入门配置 |
Mybatis入门案例【超详细】 | |
MyBatis配置文件 —— 相关标签详解 | |
Mybatis模糊查询——三种定义参数方法和聚合查询、主键回填 | |
Mybatis动态SQL查询 --(附实战案例--8888个字--88质量分) | |
Mybatis分页查询——四种传参方式 | |
Mybatis一级缓存和二级缓存(带测试方法) | |
Mybatis分解式查询 | |
Mybatis关联查询【附实战案例】 | |
MyBatis注解开发---实现增删查改和动态SQL | |
MyBatis注解开发---实现自定义映射关系和关联查询 |
3. Spring系列专栏文章
Spring系列专栏 | Spring IOC 入门简介【自定义容器实例】 |
IOC使用Spring实现附实例详解 | |
Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式 | |
Spring DI简介及依赖注入方式和依赖注入类型 | |
Spring IOC相关注解运用——上篇 | |
Spring IOC相关注解运用——下篇 | |
Spring AOP简介及相关案例 | |
注解、原生Spring、SchemaBased三种方式实现AOP【附详细案例】 | |
Spring事务简介及相关案例 | |
Spring 事务管理方案和事务管理器及事务控制的API | |
Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务 |
相关文章:

Spring DI简介及依赖注入方式和依赖注入类型
目录 一、什么是依赖注入 二、依赖注入方式 1. Setter注入 2. 构造方法注入 3. 自动注入 三、依赖注入类型 1. 注入bean类型 2. 注入基本数据类型 3. 注入List集合 4. 注入Set集合 5. 注入Map集合 6. 注入Properties对象 往期专栏&文章相关导读 1. Maven系…...
ES6栈方法和队列方法
在 JavaScript 这门语言中,栈和队列是非常重要的数据结构,它们可以帮助我们更好地组织和管理数据。我们可以使用 ES6 标准中新增的方法来实现栈和队列的操作。这篇文章将介绍 ES6 中数组的栈方法和队列方法。 栈(Stack) 栈是一种后进先出(L…...

EventBus(事件总线)的使用和源码的简单解析
Google Guava EventBus(事件总线)的使用和源码的简单解析 什么是EventBus? 事件总线(EventBus)是一种广泛用于软件架构中的设计模式,用于实现解耦和松散耦合的通信机制。它可以帮助组织和管理应用程序中不同组件之间的通信&…...

《汇编语言》- 读书笔记 - 第2章-寄存器
《汇编语言》- 读书笔记 - 第2章-寄存器 2.0 8086CPU 寄存器段地址:偏移地址 2.1 通用寄存器2.2 字在寄存器中的存储2.3 几条汇编指令表2.1汇编指令举例表2.2 程序段中指令的执行情况之一问题 2.1表2.3 程序段中指令的执行情况之二问题 2.2 检测点 2.12.4 物理地址2.5 16位结构…...

English Learning - L3 综合练习 1 VOA-Color 2023.04.26 周三
English Learning - L3 综合练习 1 VOA-Color 2023.04.26 周三 主题整体听一遍精听句子 1扩展 way of doing | way to do sth 句子 2扩展 Expression扩展 base 句子 3句子 4扩展 red-hot 句子 5句子 6扩展 fiery 句子 7句子 8句子 9句子 10句子 11扩展 born 句子 12句子 13句子…...

50道web前端工程师面试题及答案解析,你学会了吗
简介:本文包含了50个实用的前端面试题及答案解析,涵盖了HTML、CSS、JavaScript、DOM、Ajax、MVC、模块化、ES6、SPA、Webpack、Babel、Virtual DOM、响应式设计、移动优先设计、响应式图片、CSS 预处理器、后处理器、模块化、布局、盒模型、浮动、定位、…...

【链表OJ题 1】反转链表
目录 题目来源: 代码实现 1、方法一 1.1分析 2、方法二 2.1 分析 题目来源: 力扣 题目描述: 代码实现 1、方法一 struct ListNode* reverseList(struct ListNode* head) {struct ListNode* prev NULL, * cur head;while (cur){st…...
【华为OD机试真题】计算网络信号 (javaC++python)100%通过率 超详细代码注释
计算网络信号 知识点广搜数组 时间限制:1s 空间限制:256MB 限定语言:不限 题目描述: 网络信号经过传递会逐层衰减,且遇到阻隔物无法直接穿透,在此情况下需要计算某个位置的网络信号值,注意:网络信号可以绕过阴隔物array[m][n]的一维数组代表网格地图,array[i][j]=0代表i…...

Tomcat8和Tomcat9乱码问题
今天新开了一个小项目,我丢,乱码了,咋回事,好久没遇到过了,都忘了咋回事。今天必须记录下来,避免继续踩坑 Tomcat 8 不需要进行任何配置即可,它默认的是GBK,而win10 win7 默认的也是…...

Lesson13 IP协议
IP: 提供一种能力,将数据从A主机送到B主机的能力,但不一定会成功 主机 : 配有 IP 地址 , 但是不进行路由控制的设备 ; 路由器: 即配有 IP 地址 , 又能进行路由控制 ; 节点 : 主机和路由器的统称; 协议头格式 如何封装和解包: 定长报头 自描述字段 如何交付(分用) : 8…...
【每日一题Day192】LC1033移动石子直到连续 | 分类讨论 贪心
移动石子直到连续【LC1033】 三枚石子放置在数轴上,位置分别为 a,b,c。 每一回合,你可以从两端之一拿起一枚石子(位置最大或最小),并将其放入两端之间的任一空闲位置。形式上,假设这…...

2023年软件测试常见面试题100%问必背全套教程
随着数字化时代的到来,软件测试越来越受到重视。在未来的几年里,软件测试将继续成为信息技术领域中的热门职业之一。如果你是一名正在寻找或准备进入软件测试行业的人,那么这套常见面试题全套教程对你来说会非常有用。 这套教程旨在帮助你了…...

TypeScript 基本概念
TypeScript 是什么? 目标:能够说出什么是 TypeScript TS 官方文档 TS 中文参考 - 不再维护 TypeScript 简称:TS,是 JavaScript 的超集,JS 有的 TS 都有 TypeScript Type JavaScript(在 JS 基础之上…...

libfacedetection 人脸检测库 检测速度慢的问题
目录 一、libfacedetection 性能介绍 英特尔CPU 使用AVX2指令集 使用AVX512指令集 嵌入式设备 二、加速检测速度 libfacedetetion的前向推理速度很快的原因 使用axv2加速指令 一、libfacedetection 性能介绍 在上一篇文章中,我发现使用摄像头检测,构…...

项目骨架搭建
CSS样式补充 精灵图 CSS精灵图(CSS Sprites)是一种网页优化技术,通过将多个小图像合并成一个大图像,然后通过CSS的背景定位(background-position)属性来显示对应的图像部分。这种技术可以减少HTTP请求次数…...

“火灾不分昼夜,安全在我心中”——五一前厂房消防检查纪实
检查人员: Scott, Jason, Willson, Hanson 检查时间: 2023年4月28日 检查地点: 1厂房、2厂房室内外 检查内容: 一、室内外消火栓: 室内栓外观正常; 室外栓: 栓体防冻防尘套破损、遗失,消防栓缺少防撞保护; 按规定距离厂房外墙不宜小于5…...

UNIX环境高级编程——进程关系
9.1 引言 本章详细说明进程组以及会话的概念,还将介绍登录shell(登录时所调用的)和所有从登录shell启动的进程之间的关系。 9.2 终端登录 9.3 网络登录 9.4 进程组 每个进程除了有一进程ID之外,还属于一个进程组,进…...
C# ref和out用法和区别
首先:两者都是按地址传递的,使用后都将改变原来参数的数值。 其次:ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空&am…...
信息复制的革命:印刷术【提高信噪比】
文章目录 引言I 保证信息不被噪音所影响1.1 校对抄写错误的方法1.2 印刷术II 雕版印刷和活字印刷2.1 雕版印刷术2.2 毕昇的胶泥活字印刷2.3 古腾堡的铅活字印刷引言 科学的诞生,丰富了信息产生的源头。文字和纸张,加速了信息的传播和文明的进步。I 保证信息不被噪音所影响 复…...

【MySQL】事务
事务是一组操作的集合,我们将一组操作视为一个整体,所以事务里面的操作的时候要么同时成功,要么同时失败,之所以会有事务也是因为我们在实际生活中会用到 最典型的例子就是转账操作:A向B进行转账,A这边扣款成功的同时B那边一定是收款成功的,如果没有事务的话就会出现A扣款成功但…...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...
mcts蒙特卡洛模拟树思想
您这个观察非常敏锐,而且在很大程度上是正确的!您已经洞察到了MCTS算法在不同阶段的两种不同行为模式。我们来把这个关系理得更清楚一些,您的理解其实离真相只有一步之遥。 您说的“select是在二次选择的时候起作用”,这个观察非…...

多模态大语言模型arxiv论文略读(112)
Assessing Modality Bias in Video Question Answering Benchmarks with Multimodal Large Language Models ➡️ 论文标题:Assessing Modality Bias in Video Question Answering Benchmarks with Multimodal Large Language Models ➡️ 论文作者:Jea…...

SpringSecurity+vue通用权限系统
SpringSecurityvue通用权限系统 采用主流的技术栈实现,Mysql数据库,SpringBoot2Mybatis Plus后端,redis缓存,安全框架 SpringSecurity ,Vue3.2Element Plus实现后台管理。基于JWT技术实现前后端分离。项目开发同时采 …...
CMake系统学习笔记
CMake系统学习笔记 基础操作 最基本的案例 // code #include <iostream>int main() {std::cout << "hello world " << std::endl;return 0; }// CMakeLists.txt cmake_minimum_required(VERSION 3.0)# 定义当前工程名称 project(demo)add_execu…...