初识依赖注入(DI)
Spring框架的核心功能之一就是通过依赖注入的方式来管理Bean之间的依赖关系。
1、基于构造函数的DI,当容器调用带有一组参数的类构造函数时,基于构造函数的 DI 就完成了,其中每个参数代表一个对其他类的依赖。
(1)A 不应该担心 B 的实现。B 将会独立实现,并且在 A 实例化的时候将提供给 A,整个过程是由 Spring 框架的控制。
(2). java文件:
package com.xxx;
public class A {
private B b;
public A(B b) {
this.b = b;
}
public void a() {
b.xxx();
}
}
(3).xml文件:
<bean id="a" class="xxx.a">
<constructor-arg ref="b"/>
</bean>
<bean id="b" class="xxx.b">
</bean>
<bean xxx c:name="John Doe" c:spouse-ref="jane"/> //构造器注入可以用c-namespace
2、构造函数参数解析:
问题:如果存在不止一个参数时,当把参数传递给构造函数时,可能会存在歧义。解决如下:
(1)构造函数的参数在 bean 定义中的顺序就是把这些参数提供给适当的构造函数的顺序就可以了。
(2)使用 type 属性显式的指定了构造函数参数的类型,容器也可以使用与简单类型匹配的类型。
(3)使用 index 属性来显式的指定构造函数参数的索引。(最好)
对应 .xml文件:
<constructor-arg type="java.lang.String" value="xxx"/>
<constructor-arg index="0" value="xxx"/>
3、beans 的 setter 方法的DI,当容器调用一个无参的构造函数或一个无参的静态 factory 方法来初始化你的 bean 后,通过容器在你的 bean 上调用设值函数,基于设值函数的 DI 就完成了。
(1)唯一的区别就是在基于构造函数注入中,我们使用的是〈bean〉标签中的〈constructor-arg〉元素,而在基于设值函数的注入中,我们使用的是〈bean〉标签中的〈property〉元素。
(2)XML 配置文件可以使用 p-namespace 以一种更简洁的方式重写
<bean xxx>
<property name="name" value="John Doe"/>
<property name="spouse" ref="jane"/>
</bean>
<bean xxx p:name="John Doe" p:spouse-ref="jane"/> //使用前加约束
4、注入内部 Beans,Java 内部类是在其他类的范围内被定义的,同理,inner beans 是在其他 bean 的范围内定义的 bean。
<bean id="outerBean" class="...">
<property name="xxx">
<bean id="innerBean" class="..."/>
</property>
</bean>
5、注入集合
(1)<list> 有助于连线,如注入一列值,允许重复。
(2)<set> 它有助于连线一组值,但不能重复。
(3)<map> 它可以用来注入名称-值对的集合,其中名称和值可以是任何类型。
(4)<props> 它可以用来注入名称-值对的集合,其中名称和值都是字符串类型。
<list>
<ref bean="address1"/>
<value>Pakistan</value>
</list>
<set>
<ref bean="address1"/>
<value>Pakistan</value>
</set>
<map>
<entry key="one" value="INDIA"/>
<entry key ="two" value-ref="address1"/>
</map>
<props>
<prop key="one">INDIA</prop> //只能是字符串
</props>
<property name="xxx" value=""/> //注入空值
<property name="xxx"><null/></property> //注入null值