Spring 依赖注入

所谓依赖注入,是指在程序运行过程中,如果需要调用另一个对象协助时,无须在代码中创建按被调用者,而是依赖外部注入。

Spring的依赖注入对调用者和被调用者几乎没有任何要求,完全支持对POJO之间依赖关系的管理。

依赖注入的两种方式:

1)设值注入

设值注入是指通过setter方法传入被调用者的实例。这种注入方式简单直观,在Spring的依赖注入大量使用。

代码示例如下:

public interface Person

{
       //使用斧子的方法
       public void useAxe();
}

public interface Axe
{
       //砍方法
       public void chop();
}
//Person的实现类代码
public class Chinese implements Person
{
       //面向Axe接口编程
       private Axe axe;
       public Chinese()
       {
       }
       //设值注入所需的setter方法
       public void setAxe(Axe axe)
       {
              this.axe = axe;
       }
       public void useAxe()
       {
              System.out.println(axe.chop());
       }
}

//Axe的第一个实现类
public class StoneAxe implements Axe
{
       public StoneAxe()
       {
       }
       //实现Axe接口的chop方法
       public String chop()
       {
              retutn "石斧砍...";
       }
}

//下面采用Spring的配置文件(关键代码)将Person实例和Axe实例组织在一起
<beans>
       <bean id="chinese" class="Chinese">
              <property name="axe">
                     <ref local="stoneAxe"/>
              </property>
       </bean>
       <!--定义stoneAxe bean-->
       <bean id="stoneAxe" class="StoneAxe"/>
</beans>

//主程序部分
public class BeanTest
{
       public static void main(String[] args) throws Exception
       {
              ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml");
              Person p = (Person)ctx.getBean("chinese");
              p.useAxe();
       }
}

 

2)构造注入

所谓构造注入,指通过构造函数来完成依赖关系的设定,而不是通过setter方法。

//对前面Chinese类做相应的修改
public class Chinese implements Person
{
       private Axe axe;
       public Chinese()
       {

       }
       //构造注入所需的带参数的构造器

       public Chinese(Axe axe)
       {
              this.axe = axe;
       }
       public void useAxe()
       {
              System.out.println(axe.chop());
       }
}//此时无须Chinese类里的setAxe方法,在构造Person实例时,Spring为Person实例注入所依赖的Axe实例



//以下是构造注入的配置文件的关键代码
<beans>
       <bean id="chinese" class="Chinese">
              <constructor-arg>
                     <ref bean="stoneAxe"/>
              </constructor-arg>
       </bean>
       <bean id="stoneAxe" class="StoneAxe"/>
</beans>

前面2中方式的区别在于创建Person实例中Axe属性的时机不同————设值注入时先创建一个默认的bean实例,然后调用对应的setter方法注入依赖关系;而构造注入则在创建bean实例时,已经完成了依赖关系的注入。建议对于依赖关系无须变化的注入,尽量采用构造注入,而其他的依赖关系的注入,尽量采用设值注入。