Spring -- 依赖注入(控制反转)

依赖注入  

Spring框架的核心功能有两个:

Spring容器作为超级大工厂,负责创建、管理所有的Java对象,这些Java对象被称为Bean。

Spring容器管理容器中Bean之间的依赖关系,Spring使用一种被称为"依赖注入"的方式来管理Bean之间的依赖关系。


使用依赖注入,不仅可以为Bean注入普通的属性值,还可以注入其他Bean的引用。依赖注入是一种优秀的解耦方式,

其可以让Bean以配置文件组织在一起,而不是以硬编码的方式耦合在一起。

理解依赖注入

IoC(控制反转)和DI(依赖注入)的意思是相同的,只是表述方式不一样。

Spring -- 依赖注入(控制反转)

当某个Java对象(调用者)需要调用另一个Java对象(被依赖对象)的方法时,传统模式下通常有两种做法:

1.原始做法:调用者主动创建被依赖对象,然后再调用被依赖对象的方法。

就比如A类中要使用B类的方法,必须要先创建B类实例,再由B类实例调用B类的方法


2.简单工厂模式:调用者先找到被依赖对象的工厂,然后主动通过工厂去获取被依赖对象,最后再

调用被依赖对象的方法:

Phone p = PhoneFactory.getPhone();

p.callSomeOne(String phoneNum);

两种方式获取被依赖对象的方式都是主动的,这必然会导致调用者与被依赖对象之间的硬编码耦合,

非常不利于项目的升级和维护。使用Spring框架之后,调用者无需主动获取被依赖对象,调用者只需要

被动的接受Spring容器为调用者创建的依赖对象即可。

Spring -- 依赖注入(控制反转)


核心配置文件中的定义:

Spring -- 依赖注入(控制反转)


最后Java代码中就不需要主动去创建依赖对象了,这个依赖的过程由Spring实现:

Spring -- 依赖注入(控制反转)

由此可以见,使用了Spring后,调用者获取被依赖对象的方式由原来的主动获取,变成了被动接受 ,

所以Spring的创始人称之为控制反转。


但是从Spring的角度来看,Spring容器负责将被依赖的对象赋值给调用者的成员变量,相当于为调用者

注入它依赖的实例,另一个说法:依赖注入就是由此得来的。


实现依赖注入的方式

Spring支持3中依赖注入的方式,属性注入、构造器注入、工厂方法注入(使用较少)


1.属性注入

属性注入是指IoC容器通过成员变量的setter方法来注入bean的属性值或者被依赖对象。这种注入方式简单、

直观,因而再Spring的依赖注入里大量使用。属性注入使用<property>元素,使用name属性指定bean的属性

名称,value属性指定属性值

Spring -- 依赖注入(控制反转)


2.构造器注入

利用构造器来设置依赖关系的方式,被称为构造注入。通俗来说,就是驱动Spring在底层以反射方式

执行带指定参数的构造器,当执行带参数的构造器时,就可利用构造器参数对成员变量进行初始化:


bean类:

Spring -- 依赖注入(控制反转)

构造器注入的传参方式有三种:

1.按照索引匹配入参:

Spring -- 依赖注入(控制反转)

索引从0开始,表示构造器参数列表中的顺序,这种方式的缺点也很明显:

参数列表的顺序如果调整了,配置文件也需要跟着调整。


2.按类型匹配入参:

Spring -- 依赖注入(控制反转)

type的值是类型的全路径,这里constructor标签的顺序也表示参数列表的顺序,

如果构造器中列表是这样的:(String name , String sex , int age),那么为name

赋值的constructor标签应该放在第一位,sex第二,age第三。

 

3.根据属性名入参:

Spring -- 依赖注入(控制反转)

这种方式是最稳的了,不多BB。


Spring -- 依赖注入(控制反转)


自动装配

Spring IOC 容器可以自动装配 Bean,需要做的仅仅是在 <bean> 的 autowire 属性里指定自动装配的模式,

它能够将当前实例中所有的对象属性全部进行填充。

Spring -- 依赖注入(控制反转)

byType是根据类型自动装配,但要求是依赖Bean在容器中只能有一个实例。

若IoC容器中有多个与目标Bean类型一致的Bean,容器将无法判断哪个Bean最适合该属性,会报错。


byName是根据名称自动装配,要求是依赖的Bean的名称和属性名设置的完全相同。

这个属性名指的是Bean中定义的字段名:

Spring -- 依赖注入(控制反转)


那么在配置文件中对应的依赖bean的id值,也得是a:

Spring -- 依赖注入(控制反转)

自动装配的缺点:

1.在配置文件里设置autowire属性进行自动装配将会装配Bean的所有属性,如果只希望装配个别属性时,

autowire属性就不够灵活了。


2.autowire属性要么根据类型自动装配,要么根据名称自动装配,不能两者兼有之。