在我们写代码的过程中,通常会用new来产生一个对象,但是这样操作的后果会使得代码难于管理。
而Spring框架为我们提供了一个控制反转(IOC,Inversion of Control)的思想。意思是原来由程序员new出来的对象,现在不这样做了,而是把它“反转”。由Spring容器去产生管理这些对象。而依赖注入(DI,Dependency Injection)就是实现控制反转的其中一种方式。
下面是四种依赖注入方式的实例:
1、set注入:
这是一种简单的注入方式,首先新建一个名叫IOCMain的类,类中需要实例化一个IOCdependency的对象。然后定义一个IOCdependency的成员变量,并建立get和set方法。
private IOCdependency IOCdependency;
// 第一种方式,set方式
public void setIOCdependency(IOCdependency iocdenpendency) {
this.IOCdependency = iocdenpendency; }
public IOCdependency getIOCdependency() {
return IOCdependency;
}
public void showOk(){
IOCdependency.output();
}
随后编写Spring的配置文件applicationContext.xml。<bean>中的name为类的一个别名,而class为类的完整名称。
由于在IOCMain的类中存在IOCdependency属性,因此要在<bean>中设置属性<property>,name为属性的名称,
ref指向名为IOCdependency的bean
<!-- 第一种方法,set方法依赖注入配置 -->
<bean id="IOCMain" class="com.elish.model.IOCMain">
<!--依赖注入,注入当前属性 -->
<property name="IOCdependency" ref="IOCdependency"></property>
</bean>
<bean name="IOCdependency" class="com.elish.model.IOCdependency"></bean>
2、构造器注入:
构造器注入指的是在类中构造带参数的构造方法实现类的注入,在这次的例子中就是在IOCMain的类中创建IOCdependency的构造方法,通过该构造方法实现注入,而不需要set函数。
// 第二种方式,构造器方式,在构造方法中调用IOCdepedency,达到注入的效果
public IOCMain(IOCdependency iocdependency){
this.IOCdependency=iocdependency; }
在配置文件中,不再用<property>标签,而是用<constructor-arg>标签代替,其中ref指向IOCdependency的bean,当存在多个参数时,有可能存在某些参数是同样类型的情况,为了确定参数的位置,可以为每个参数设置索引index,确定参数的位置
<!-- 第二种方法,构造器方法依赖注入配置 -->
<bean id="IOCMain" class="com.elish.model.IOCMain">
<!--创建构造器注入,如果主类有带参的构造方法则需添加此配置 -->
<constructor-arg ref="IOCdependency" index="0"></constructor-arg>
</bean>
<bean name="IOCdependency" class="com.elish.model.IOCdependency"></bean>
3、静态工厂的方式注入
通过建立静态工厂的方式进行注入,首先创建一个静态工厂IOCstaticFactory的类,然后在工厂类中创建getStaticFactory()的方法
public class IOCstaticFactory {
public static final IOCdependency getStaticFactory(){
return new IOCdependency();
}
}
在IOCMain中,创建与set方法注入相同的set方法。
// 第三种方式,静态工厂方式,在工厂类中返回静态IOCFactory对象
public void setIOCdependency(IOCdependency iocdenpendency) {
this.IOCdependency = iocdenpendency; }
与上面两个方法不同,这次在配置文件中不会直接定义IOCdependcy的bean,而是定义静态工厂IOCstaticFactory的bean,在这个bean中,需要配置factory-method="getStaticFactory"来指定调用哪个工厂方法。并在IOCMain的bean中定义指向静态工厂bean的<property>。
<!-- 第三种方法,静态工厂方法 -->
<bean id="IOCMain" class="com.elish.model.IOCMain">
<!--使用静态工厂的方法注入对象,对应下面的配置文件 -->
<property name="IOCdependency" ref="IOCdependency"></property>
</bean>
<bean name="IOCdependency" class="com.elish.model.IOCstaticFactory" factory-method="getStaticFactory"></bean>
4、动态工厂的方式注入
与静态工厂方式注入的方法不同,它需要先创建工厂类再调用方法
public class IOCFactory {
public IOCdependency getFactory(){
return new IOCdependency();
}
}
这里也需要set方法
// 第四种方式,实体工厂方式,在工厂类中返回实体IOCFactory对象
public void setIOCdependency(IOCdependency iocdenpendency) {
this.IOCdependency = iocdenpendency; }
与静态工厂的方法不同,这里需要定义IOCdependency的bean,并指定factory-bean和factory-method
<!-- 第四种方法,实体工厂方法 -->
<bean id="IOCMain" class="com.elish.model.IOCMain">
<!-- 使用实例工厂的方法注入对象,对应下面的配置文件 -->
<property name="IOCdependency" ref="IOCdependency"></property>
</bean>
<!-- 此处获取对象的方式是从工厂类中获取实例方法 -->
<bean name="IOCFactory" class="com.elish.model.IOCFactory"></bean>
<bean name="IOCdependency" factory-bean="IOCFactory"
factory-method="getFactory"></bean>
5、总结:在通常情况下,用第一种和第二种的情况较多,并且要多加锻炼才能熟练掌握