前面的是没有依赖时如何创建对象,现在是有依赖时如何创建对象。
IOC的作用:降低程序间的依赖关系。但是不是消除依赖关系,所以程序间必然有一些依赖关系,依赖关系的管理以后都交给spring来维护,什么是依赖关系呢?就是在当前类中需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中告诉spring我们用哪个类的对象。
能注入的数据有三类:
1、 基本类型的包装类和String
2、 其他Bean类型(在配置文件中或注解配置过的Bean,即spring容器中)
3、 集合类型
依赖注入的方式有三种:
1、 使用构造函数提供
2、 使用set方法提供
3、 使用注解提供
一、依赖作为参数使用构造函数注入
将注解@autowired加在有参构造函数上
service
@Service public class UnitInfoService { private UnitInfoMapper unitInfoMapper; @Autowired public UnitInfoService(UnitInfoMapper unitInfoMapper){ this.unitInfoMapper = unitInfoMapper; } }
controller
@RestController public class UnitInfoController { private UnitInfoService unitInfoService; @Autowired public UnitInfoController(UnitInfoService unitInfoService) { this.unitInfoService = unitInfoService; } }
当构造方法只有一个,且该构造方法是有参构造时,@Autowired注解可以省略。
@Service public class UnitInfoService { private UnitInfoMapper unitInfoMapper; public UnitInfoService(UnitInfoMapper unitInfoMapper){ this.unitInfoMapper = unitInfoMapper; } }
步骤:
1、 在类中定义可注入的变量
先来演示类型为基本类型的包装类、字符串,Date为其他Bean类型
在你不提供任何构造函数的情况下,系统会赠送一个默认构造函数。现在已经定义了一个满参构造函数,所以没有默认构造函数了,所以使用默认构造函数创建Bean对象会报错,应该用满参构造函数创建Bean对象。
2、使用constructor-arg标签,标签出现的位置是bean标签的内部。
Constructor-arg标签中的属性:
1)、type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
这样只能把test变量注入给带参构造函数中String类型的参数,但是如果构造函数的参数中有两个String类型的参数就不知道给哪个注入了。故type属性不能独立实现注入的功能
2)、index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
3)、name:用于指定给构造函数中指定名称的参数赋值
常用的以上三个用于指定给构造函数中哪个参数赋值,常用name属性。
4)、value:用于提供基本类型的包装类和String类型的数据
5)、ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
Age是Integer类型,而value=“18”,在xml中写的时候,value值都是字符串。Spring能把这些类型进行转换的。而birthday是Date类型,而value=“1970-01-01”,并不是日期类型,而只是普通的字符串,你用字符串给对象赋值,spring是无法转换的。我们可以配置一个日期对象,然后用ref属性引用关联的Bean对象。
3、测试:获取Bean对象,调用方法
结果:
优势:在创建Bean对象时,注入数据是必须的操作,否则对象无法创建成功。
弊端:改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。如果我们在bean.xml中少提供任何一个参数,对象都创建不出来,除非你在类中加很多重载的构造函数。
在实际开发中,除了必须采用这种方式之外,其他情况一般不用构造函数注入的方式来创建对象。
二、依赖作为参数使用set方法注入
set注入是将注解autowired添加到该属性的set方法上
service
@Service public class UnitInfoService { private UnitInfoMapper unitInfoMapper; @Autowired public void setUnitInfoMapper(UnitInfoMapper unitInfoMapper){ this.unitInfoMapper = unitInfoMapper; } }
controller
@RestController public class UnitInfoController { private UnitInfoService unitInfoService; @Autowired public void setUserService(UnitInfoService unitInfoService) { this.unitInfoService = unitInfoService; } }
步骤:
1、在类中添加Set方法:(注意:注入只需要set方法,不需要get方法)
由于没有提供任何构造函数,系统会赠送一个默认构造函数
2、使用property标签,标签出现的位置是bean标签的内部
property标签的属性
1、name:用于指定注入时所调用的set方法名称,即属性,而不是成员变量。不过一般情况属性和成员变量相同
2、value:用于提供基本类型和String类型的数据
3、ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
3、测试:获取Bean对象,调用方法
结果:
优势:创建对象时没有明确的限制,可以直接使用默认构造函数。解决了构造函数注入的弊端问题。
弊端:如果有某个成员必须有值,则set方法无法保证一定注入,即获取对象时有可能set方法没有执行。因为创建对象时没有参数的限制,而是调用默认构造函数,有可能调用默认构造函数用,这个时候可能数据就没有值。
与使用构造函数注入相比,set方法注入更常用。
三、集合类型的注入
包括数组、List集合、Set集合、Map集合、Properties属性集
1、在类中添加数组、List集合、Set集合、Map集合、Properties属性集类型的成员变量,并生成set方法以注入依赖。
2、property标签的value属性和ref属性都注入不了集合类型,这时使用property的子标签array、list、set、map、props。
Props标签的属性只有key一个,key的值是标签体中的内容。
用于给List结构集合注入的标签有list、array、set
用于给Map结构集合注入的标签有Map、props
结构相同,标签可以互换,即list、array、set三个标签可以互换,Map和props标签可以互换。
依赖注入方式选择
1. 强制依赖使用构造器进行,使用 setter 注入有概率不进行注入导致 null 对象出现
2. 可选依赖使用 setter 注入进行,灵活性强
3. Spring 框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
4. 如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用 setter 注入完成可选依赖的注入
5. 实际开发过程中还要根据实际情况分析,如果受控对象没有提供 setter 方法就必须使用构造器注入 6. 自己开发的模块推荐使用 setter 注入
标签:unitInfoMapper,set,DI,Spring,dependency,标签,类型,注入,构造函数 From: https://www.cnblogs.com/zwh0910/p/14618242.html