1.为什么要使用依赖注入?
假设有两个组件A和B,且A是一个类,类有一个方法importantMethod需要用到B
public class A {
public void importantMethod(){
B b = ... //get an instance of B
b.usefulMethod();
}
}
要使用B,必须先获取组件B的实例引用。若B是一个具体类,则可以通过new关键字创建组件B。但是如果B是一个接口,且有多个实现,我们固然可以任意选择接口B的一个实现类,但这就意味着A的可重用性大大降低了,因为无法获取B的其他实现。
依赖注入是这样解决此类问题的,接管对象的创建工作,并将改对象的引用注入达到需要该对象的组件。
Spring的依赖注入方式:
1.构造器注入(Spring1.0)
public class A {
private B b;
public A(B b){
this.b=b;
}
public void importantMethod(){
b.usefulMethod();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="A" class="A">
<constructor-arg ref="b" />
</bean>
<bean id="b" class="B" />
</beans>
2.set方法注入(Spring1.0)
public class A {
private B b;
public void importantMethod(){
b.usefulMethod();
}
public void setB(B b){
this.b=b;
}
}
<beans
xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config/>
<bean id="A" class="A">
<property name="b" ref="B"></property>
</bean>
Constructor注入 vs Setter注入
Constructor注入能强制要求调用者注入构造函数中的所有参数,否则在容器初始化时就会失败;但是如果要注入的对象过多,就会导致构造函数过于庞大。
Setter注入,将原本庞大的构造函数。拆解为一个小的构造函数和许多个set方法。set同问注入不能保证对象一定会被注入,但是可以使用@required注解,强制要求使用者注入对象,否则会在容器初始化时报错。