0


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

在这里插入图片描述

文章目录

一、说明

  • 全称Dependency Injection(DI)
  • 与IoC的关系

IoC和DI其实说的是一个意思,可以这么说:IoC是一种思想,DI是对这种思想的一种具体实现

  • 依赖关系的管理

以后都交给spring来维护,在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明。

  • 依赖关系的维护​ 称之为依赖注入。
  • 能注入的数据:有三类​ 基本类型和String。​ 其他bean类型(在配置文件中或者注解配置过的bean)​ 复杂类型/集合类型
  • 注入的方式:有三种​ 第一种:使用构造函数提供​ 第二种:使用set方法提供​ 第三种:使用注解提供(参考第七章节)

二、构造函数注入

2.1、方式一【index索引方式】

2.1.1、定义Bean

publicclassPerson{privateInteger id;privateString name;// 姓名privateInteger age;// 年龄privateDouble weight;// 体重publicPerson(Integer id,String name,Integer age){this.id = id;this.name = name;this.age = age;}}

2.1.2、主配置文件中配置Bean

<beans><beanid="person"class="cn.bdqn.Person"><constructor-argindex="0"value="1"/><constructor-argindex="1"value="王浩"/><constructor-argindex="2"value="20"/></bean></beans>

2.1.3、测试

@TestpublicvoidtestPerson()throwsException{// 1、读取主配置文件信息,获取核心容器对象ApplicationContext ac =newClassPathXmlApplicationContext("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属性初始化,并专门为其添加构造方法

publicclassPerson{privateInteger id;privateString name;// 姓名privateInteger age;// 年龄privateDouble weight;// 体重publicPerson(Integer id,String name,Integer age){this.id = id;this.name = name;this.age = age;}// 专门为weight属性定义的构造方法publicPerson(Integer id,String name,Double weight){this.id = id;this.name = name;this.weight = weight;}}

2.2.2、主配置文件配置Bean

<beans><beanid="person"class="cn.bdqn.Person"><constructor-argindex="0"value="1"/><constructor-argindex="1"value="王浩"/><constructor-argindex="2"value="180"/></bean></beans>

2.2.3、测试

@TestpublicvoidtestPerson()throwsException{// 1、读取主配置文件信息,获取核心容器对象ApplicationContext ac =newClassPathXmlApplicationContext("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><beanid="person"class="cn.bdqn.Person"><constructor-argindex="0"type="java.lang.Integer"value="1"/><constructor-argindex="1"type="java.lang.String"value="王浩"/><constructor-argindex="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><beanid="person"class="cn.bdqn.Person"><constructor-argname="id"value="2"/><constructor-argname="name"value="史周冲"/><constructor-argname="age"value="3"/></bean></beans>

2.3.3、测试

@TestpublicvoidtestPerson()throwsException{// 1、读取主配置文件信息,获取核心容器对象ApplicationContext ac =newClassPathXmlApplicationContext("beans.xml");Person person =(Person) ac.getBean("person");System.out.println(person);// Person{id=1, name='王浩', age=3}}

2.4、补充细节

2.4.1、定义Bean

publicclassPerson{privateInteger id;privateString name;// 姓名privateDate birthday;// 出生日期publicPerson(Integer id,String name,Date birthday){this.id = id;this.name = name;this.birthday = birthday;}}

2.4.2、主配置文件配置Bean

<beans><beanid="person"class="cn.bdqn.Person"><constructor-argname="id"value="2"/><constructor-argname="name"value="史周冲"/><constructor-argname="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><beanid="person"class="cn.bdqn.Person"><constructor-argname="id"value="2"/><constructor-argname="name"value="史周冲"/><!-- 注意:用了ref属性--><constructor-argname="birthday"ref="currentDate"/></bean><!-- 定义日期Bean,Spring就会帮助我们new一个Date对象--><beanid="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

publicclassUser{privateString name;privateDate born;publicvoidsetName(String name){this.name = name;}publicvoidsetBorn(Date born){this.born = born;}}

说明:set注入方式不必生成get方法

3.2、主配置文件配置Bean

<beanid="currentDate"class="java.util.Date"/><beanid="user"class="cn.bdqn.User"><propertyname="name"value="宋炜烨"/><propertyname="born"ref="currentDate"/></bean>

3.3、测试

@TestpublicvoidtestUser()throwsException{// 1、读取主配置文件信息,获取核心容器对象ApplicationContext ac =newClassPathXmlApplicationContext("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

publicclassCat{privateString[] arrs;publicvoidsetArrs(String[] arrs){this.arrs = arrs;}}

4.1.2、主配置文件配置Bean

<beans><beanid="cat"class="cn.bdqn.Cat"><propertyname="arrs"><array><value>崔灿</value><value>时贝妮</value></array></property></bean></beans>

4.2、注入List类型【list】

4.2.1、定义Bean

publicclassCat{privateList<String> arrList;publicvoidsetArrList(List<String> arrList){this.arrList = arrList;}}

4.2.2、主配置文件配置Bean

<beans><beanid="cat"class="cn.bdqn.Cat"><propertyname="arrList"><list><value>乔峰</value><value>马夫人</value></list></property></bean></beans>

4.3、注入Set类型【set】

4.3.1、定义Bean

publicclassCat{privateSet<String> arrSet;publicvoidsetArrSet(Set<String> arrSet){this.arrSet = arrSet;}}

4.3.2、主配置文件配置Bean

<beans><beanid="cat"class="cn.bdqn.Cat"><propertyname="arrSet"><set><value>段誉</value><value>鸠摩智</value></set></property></bean></beans>

4.4、注入Map类型【Map】

4.4.1、定义Bean

publicclassCat{privateMap<String,Object> arrMap;publicvoidsetArrMap(Map<String,Object> arrMap){this.arrMap = arrMap;}}

4.4.2、主配置文件配置Bean

<bean><propertyname="arrMap"><map><entrykey="S001"value="彭依凝"/><entrykey="S002"value="段康家"/><entrykey="S003"value="王浩"/></map></property></bean>

4.5、注入Properties类型

4.5.1、定义Bean

publicclassCat{privateProperties props;publicvoidsetProps(Properties props){this.props = props;}}

4.5.2、主配置文件配置Bean

<beanid="cat"class="cn.bdqn.Cat"><propertyname="props"><props><propkey="A001">虚竹</prop><propkey="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 数据库 java

本文转载自: https://blog.csdn.net/m0_63947499/article/details/134577569
版权归原作者 陈橘又青 所有, 如有侵权,请联系我们删除。

“【Spring进阶系列丨第五篇】详解Spring中的依赖注入”的评论:

还没有评论