无论是依赖注入,还是控制反转,其含义完全相同。 当某个Java对象(调用者)需要调用另一个Java对象(被依赖对象)的方法时,在传统模式下通常有两种做法:
1、原始做法: 调用者主动创建被依赖对象,然后再调用被依赖对象的方法。
2、简单工厂模式: 调用者先找到被依赖对象的工厂,然后主动通过工厂去获取被依赖对象,最后再调用被依赖对象的方法。
注意上面的主动二字,这必然会导致调用者与被依赖对象实现类的硬编码耦合,非常不利于项目升级的维护。使用Spring框架之后,调用者无需主动获取被依赖对象,调用者只要被动接受Spring容器为调用者的成员变量赋值即可,由此可见,使用Spring后,调用者获取被依赖对象的方式由原来的主动获取,变成了被动接受。
使用依赖注入,不仅可以为Bean注入普通的属性值,还可以注入其他Bean的引用。依赖注入是一种优秀的解耦方式,其可以让Bean以配置文件组织在一起,而不是以硬编码的方式耦合在一起
1. setter注入
即当前对象只需要为其依赖对象所对应的属性添加setter方法,[IOC]容器通过此setter方法将相应的依赖对象设置到被注入对象的方式即setter方法注入。
这里以Sing(唱),Song(歌)高度偶合的示例来说明:
来个Song类
public class Song {
private String name;
private int number;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
再来个Sing类
/**
* 设置注入
*/
public class Sing {
private Song song;
public void setSong(Song song) {
this.song = song;
}
public void startSing(){
System.out.println("开始唱"+song.getName());
}
}
配置文件:
<bean id="song" class="com.XXX.spring.type2.Song">
<property name="name" value="中国人"/>
<property name="number" value="2"/>
</bean>
<bean id="sing" class="com.XXX.spring.type2.Sing">
<property name="song" ref="song"/>
</bean>
集合注入配置
<bean id="person" class="com.XXX.entity.Person">
<property name="names">
<list>
<value>张三</value>
<value>李四</value>
<value>王麻子</value>
</list>
</property>
<!--Set集合的注入-->
<property name="interests">
<set>
<value>打官司</value>
<value>给员工敲代码</value>
<value>打业主</value>
</set>
</property>
<!--Map注入-->
<property name="jobs">
<map>
<entry key="律师" value="法外狂徒"></entry>
<entry key="IT" value="项目经理"></entry>
<entry key="保安" value="保安队长"></entry>
</map>
</property>
<!--Properties注入-->
<property name="wifes">
<props>
<prop key="first"> 张三老婆</prop>
<prop key="second">李四老婆</prop>
<prop key="third"> 王麻子老婆</prop>
</props>
</property>
</bean>
2. 构造器注入
即被注入对象可以通过在其构造方法中声明依赖对象的参数列表,让外部(通常是IOC容器)知道它需要哪些依赖对象,然后IOC容器会检查被注入对象的构造方法, 取得其所需要的依赖对象列表,进而为其注入相应对象
1、修改setter注入中的Sing
/**
* 构造方法注入
*/
public class Sing {
private Song song;
public Sing(Song song) {
this.song = song;
}
public void startSing(){
System.out.println("开始唱"+song.getName());
}
}
2、配置文件修改
<bean id="song3" class="com.XXX.spring.type3.Song">
<property name="name" value="中国人"/>
<property name="number" value="2"/>
</bean>
<bean id="sing3" class="com.XXX.spring.type3.Sing">
<constructor-arg index="0" ref="song3"/>
</bean>
构造参数注入相比比较麻烦,平时在使用时还是setter注入使用的多