前言

上篇文章中我们初步介绍了依赖注入(Dependency Injection)。今天将来介绍下spring框架中的两种依赖注入。

两种依赖注入(Dependency Injection)

  • 基于构造函数的依赖注入
  • 基于Setter方法的依赖注入

如果是强制性依赖的话建议使用基于构造函数的依赖注入,请看下面的例子:

package sirk_spring_tuto.demo;

public class TV {
private Screen screen;

public TV(Screen screen){
    this.screen = screen;
}

public void powerOn(){
    this.screen.show();
}
}



package sirk_spring_tuto.demo;

public interface Screen {
public void show();
}


package sirk_spring_tuto.demo;

public class CRTScreen implements Screen{

public void show() {
    System.out.println("CRTScreen show beautiful girls");
}

}



<?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-3.1.xsd">

    <bean id="tv" class="sirk_spring_tuto.demo.TV">
     <constructor-arg ref="screen"></constructor-arg>
    </bean>
    <bean id="screen" class="sirk_spring_tuto.demo.CRTScreen"></bean>
</beans>



package sirk_spring_tuto.demo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {

public static void main(String[] args) {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("Beans.xml");
    TV tv = (TV) ctx.getBean("tv");
    tv.powerOn();

}

} 

好了,通过上述程序运行,最终会打印CRTScreen show beautiful girls。代码很简单,首先定义了一个TV(电视机类),然后通过构造方法将Screen注入进去,这样电视机就有了显示器的 显示功能,但是电视机类并没有强耦合于Screen,内部的Screen属性只是一个接口,至于如何实现就看Spring了,我们在配置文件中将CTRScreen注入,于是就有了最终的结果。如果你不想要使用 CTRScreen了,想换个液晶显示器,之需要修改配置文件就好了,这样能明白减少类之前的耦合是多么好了吧。同样的,以这个例子,我们再来看看另一种注入方式。

如果是可选的依赖注入,则建议使用基于Setter方式的依赖注入,如下:

package sirk_spring_tuto.demo;

public class TV {
private Screen screen;

/*public TV(Screen screen){
    this.screen = screen;
}*/



public void powerOn(){
    this.screen.show();
}

public Screen getScreen() {
    return screen;
}

public void setScreen(Screen screen) {
    this.screen = screen;
}
}



<?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-3.1.xsd">

    <!-- <bean id="tv" class="sirk_spring_tuto.demo.TV">
<constructor-arg ref="screen"></constructor-arg>
    </bean> -->

    <bean id="tv" class="sirk_spring_tuto.demo.TV">
     <property name="screen" ref="screen"></property>
    </bean>
    <bean id="screen" class="sirk_spring_tuto.demo.CRTScreen"></bean>
</beans>   

此处只贴出需要修改的两个文件,一个是TV类增加Setter方法,一个是beans配置文件的修改。

XML配置文件中使用p-namespace

当有多个Setter方法注入时,你可能会配置如下的文件:

<?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-3.1.xsd">

   <bean id="man" class="com.example.Man">
      <property name="name" value="sirk"/>
      <property name="wife" ref="lucy"/>
   </bean>

  <bean name="lucy" class="com.example.Woman">
      <property name="name" value="luck"/>
  </bean>
</beans>

如果使用p-namespace方式,则可以写成如下的方式:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:p="http://www.springframework.org/schema/p"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

   <bean id="man" class="com.example.Man"
       p:name="sirk"
       p:wife-ref="lucy"/>
   </bean>

   <bean name="lucy" class="com.example.Woman"
       p:name="luck"/>
   </bean>
</beans>

通过使用p-namespace 方式简化了对于引用和基本值的处理,之需要对引用bean的p加上-ref就好了。这样,spring会自动判断出该属性是一个引用。

小结

本文介绍了spring的两种依赖注入,下篇更精彩,敬请期待~

##文档信息