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

news2024/11/22 6:30:41

在这里插入图片描述

文章目录

  • 一、说明
  • 二、构造函数注入
    • 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的其他部分开发关键任务型批处理应用

购书链接:点此进入

送书活动

参与方式:点击进入参与 公平公正公开 人少好中奖!


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1305180.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5. PyTorch——数据处理模块

1.数据加载 在PyTorch中&#xff0c;数据加载可通过自定义的数据集对象。数据集对象被抽象为Dataset类&#xff0c;实现自定义的数据集需要继承Dataset&#xff0c;并实现两个Python魔法方法&#xff1a; __getitem__&#xff1a;返回一条数据&#xff0c;或一个样本。obj[in…

unity Mesh Simplify 1.10(模型优化工具:查看面数,降低面数灯)

提示&#xff1a;文章有错误的地方&#xff0c;还望诸位大神不吝指教&#xff01; 文章目录 前言一、面板参数详解说明二、使用方法总结 前言 有时候想对模型优化一下&#xff0c;奈何又不会建模方面的。虽然我感觉它的数值不大对&#xff0c;但是不影响我们优化顶点数嘛。 Me…

LeetCode 1631. 最小体力消耗路径:广度优先搜索BFS

【LetMeFly】1631.最小体力消耗路径&#xff1a;广度优先搜索BFS 力扣题目链接&#xff1a;https://leetcode.cn/problems/path-with-minimum-effort/ 你准备参加一场远足活动。给你一个二维 rows x columns 的地图 heights &#xff0c;其中 heights[row][col] 表示格子 (ro…

【玩转TableAgent数据智能分析】TableAgent全功能详解及多领域数据分析实践(中)不同领域数据分析实践

3 电影点评数据分析实践 利用本身自带的电影点评数据&#xff0c;来具体看一下TableAgent的分析能力&#xff0c;选择电影点评数据&#xff0c;智能体会自动导入该数据DMSC20000.csv&#xff0c;大小为3.3 MB。在数据信息展示区&#xff0c;就会显示出该数据&#xff0c;并提供…

你一定要知道的Fiddler过滤器 Filters 详解

如果要对当前Fiddler的抓包进行过滤&#xff08;如过滤掉与测试项目无关的抓包请求&#xff09;&#xff0c;那功能强大的 Filters 过滤器能帮到你。 进入 Filters 选项页&#xff0c;勾选上 Use Filters&#xff0c;即启用过滤器。 Actions 四个选项说明&#xff1a; Run Fi…

SI24R03 高度集成低功耗SOC 2.4G 收发一体芯片

今天给大家介绍一款Soc 2.4G 收发一体模块-SI24R03 Si24R03是一款高度集成的低功耗无线SOC芯片&#xff0c;芯片为QFN32 5x5mm封装&#xff0c;集成了资源丰富的MCU内核与2.4G收发器模块&#xff0c;最低功耗可达1.6uA&#xff0c;极少外围器件&#xff0c;大幅降低系统应用成本…

(第8天)保姆级 PL/SQL Developer 安装与配置

PL/SQL Developer 安装与配置(第8天) 咱们前面分享了很多 Oracle 数据库的安装,但是还没有正式使用过 Oracle 数据库,怎么连接 Oracle 数据库?今天就来讲讲我学习中比较常用的 Oracle 数据库连接工具:PL/SQL DEVELOPER。 PL/SQL Developer 的安装和配置对于新手来说还是…

机器学习---Boosting

1. Boosting算法 Boosting思想源于三个臭皮匠&#xff0c;胜过诸葛亮。找到许多粗略的经验法则比找到一个单一的、高度预 测的规则要容易得多&#xff0c;也更有效。 预测明天是晴是雨&#xff1f;传统观念&#xff1a;依赖于专家系统&#xff08;A perfect Expert) 以“人无…

【Qt信号槽源码分析】

Qt信号槽源码分析 一、相关宏介绍二、示例moc文件源码解析信号发送接收过程源码解析emit signalconnect 三、关键类图&#xff1a;四、时间&空间问题五、总结 一、相关宏介绍 *要使用信号-槽功能&#xff0c;先决条件是继承QObject类&#xff0c;并在类声明中增加Q_OBJECT…

ue5材质预览界面ue 变黑

发现在5.2和5.1上都有这个bug 原因是开了ray tracing引起的&#xff0c;这个bug真是长时间存在&#xff0c;类似的bug还包括草地上奇怪的影子和地形上的影子等等 解决方法也很简单&#xff0c;就是关闭光追&#xff08;不是…… 就是关闭预览&#xff0c;在材质界面preview sc…

屠宰加工污废水处理工艺设备有哪些

屠宰加工行业对于废水处理的要求日益严格&#xff0c;为了达到环保要求&#xff0c;减少对环境造成的负面影响&#xff0c;屠宰加工污废水处理工艺设备应运而生。以下是常见的几种工艺设备&#xff1a; 1. 沉淀池&#xff1a;沉淀池是屠宰加工废水处理中常用的处理设备之一。废…

【RTOS学习】模拟实现任务切换 | 寄存器和栈的变化

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《RTOS学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 目录 &#x1f3c0;认识任务切换&#x1f3d0;切换的实质&#x1f3d0;栈中的内容&#x1f3d0;切…

scala表达式

1.8 表达式&#xff08;重点&#xff09; # 语句(statement)&#xff1a;一段可执行的代码# 表达式(expression)&#xff1a;一段可以被求值的代码&#xff0c;在Scala中一切都是表达式 - 表达式一般是一个语句块&#xff0c;可包含一条或者多条语句&#xff0c;多条语句使用“…

Fiddler如何比较两个接口请求?我来告诉你

进行APP测试时&#xff0c;往往会出现Android和iOS端同一请求&#xff0c;但执行结果不同&#xff0c;这通常是接口请求内容差异所致。 我习惯于用Fiddler抓包&#xff0c;那此时应该如何定位问题呢&#xff1f; 分别把Android和iOS的接口请求另存为TXT文件&#xff0c;然后用…

软件安全设计

目录 一&#xff0c;STRIDE 威胁建模 1&#xff0c;STRIDE 2&#xff0c;总体流程&#xff08;关键步骤&#xff09; 3&#xff0c;数据流图的4类元素 二&#xff0c;安全设计原则 三&#xff0c;安全属性 一&#xff0c;STRIDE 威胁建模 1&#xff0c;STRIDE STRIDE 是…

区块链实验室(32) - 下载arm64的Prysm

Prysm是Ethereum的共识层。 1. 下载prysm.sh curl https://raw.githubusercontent.com/prysmaticlabs/prysm/master/prysm.sh --output prysm.sh && chmod x prysm.sh2. 下载x86版prysm共识客户端 ./prysm.sh beacon-chain --download-only3.下载arm64版prysm共识客…

论文解读:Medical Transformer论文创新点解读

这篇文章其实就是基于Axial-DeepLab: Stand-Alone Axial-Attention forPanoptic Segmentation论文上进行的一些小创新 Stand-Alone Axial-Attention forPanoptic Segmentation论文解读&#xff1a; 论文解读&#xff1a;Axial-DeepLab: Stand-Alone Axial-Attention forPanop…

K8s可视化kuboard 部署

创建资产 [rootkube-master ~]# kubectl apply -f https://addons.kuboard.cn/kuboard/kuboard-v3.yaml 查看对应资源 [rootkube-master ~]# kubectl get pod -n kuboard NAME READY STATUS RESTARTS AGE kuboard-agent-2-5c4f886…

InnoDB在SQL查询中的关键功能和优化策略

文章目录 前言存储引擎介绍存储引擎是干嘛的InnoDB的体系结构 InnoDB的查询操作InnoDB的查询原理引入 Buffer Pool引入数据页Buffer Pool 的结构数据页的加载Buffer Pool 的管理Buffer Pool 的优化 总结 前言 通过上篇文章《MySQL的体系结构与SQL的执行流程》了解了SQL语句的执…

初入职场的你,为何会频繁跳槽?

大数据统计&#xff0c;初入职场的人跳槽频率相当高&#xff0c;而对于工作了2~3年的来说&#xff0c;跳槽频率也就没有那么频繁了&#xff0c;是什么原因导致了频繁跳槽&#xff1f;如何避免频繁跳槽呢&#xff1f; 是什么原因导致了跳槽&#xff1f; 不适应 从学校毕业&am…