天天看点

Spring学习笔记(二)----Constructor Injection or Setter Injection

  Spring作为一个全面的应用程序框架,不仅仅使用于Web开发,它能应用于各种应用的开发。

    Spring提供容器功能,并且具有轻量级,飞入侵性,IoC,AOP等特性。Spring的核心即是一个容器,实现了IoC的概念,把各种对象交由其管理,可以获得更多特性。Spring提供了两种应用程序框架(Application framework),BeanFactory和ApplicationContext。

    BeanFactory负责读取Bean定义文件(一般为xml或properties文件),管理对象的加载,生成,维护

对象间关系,负责Bean的生命周期。ApplicationContext的基本功能与BeanFactory相同,除此之外,它 还提供了其它功能:

   更加便捷的提取资源文件;

   支持国际化;

   ApplicationContext还可以发布事件,对事件感兴趣的Bean可以接受这些事件。

   所以建议使用ApplicationContext替代BeanFactory 对于Bean的管理,Spring可以使用Setter Injection和Constructor Injection。    下面举一个例子: (1)创建一个Bean,就叫HelloBean吧。    它具有如下属性:    private String name;

   private int number;

   private Date date;    当然还有这些属性的get和set方法。此外还有一个构造函数(没有构造函数怎么能叫Constructor Injection呢)    public HelloBean(Date date, String name, int number) {

  this.date = date;

  this.name = name;

  this.number = number;

}   还是建议有一个不带参数的构造方法。   (2)创建配置文件 <?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" " http://www.springframework.org/dtd/spring-beans.dtd "> <beans>

   <bean id="helloBean" class="com.yangsq.spring.HelloBean">

      <constructor-arg index="0">

          <bean class="java.util.Date"/>

      </constructor-arg>

      <constructor-arg index="1">

          <value>yangsq</value>

      </constructor-arg>

      <constructor-arg index="2">

          <value>123</value>

      </constructor-arg>

   </bean>

</beans>   需要说明的是index指定了注入到构造函数中参数的顺序。对于第一个参数为Date型,除了上面这种方式外,还可如下定义:   <bean id="date" class="java.util.Date"/> <bean id="helloBean" class="com.yangsq.spring.HelloBean">

      <constructor-arg index="0">

          <ref bean="date"/>

      </constructor-arg>

      ...... </bean>

两种方式不同的是第一种的Date对象仅供本bean使用,而第二个可供所有的bean定义使用。   (3)测试代码 要import ApplicationContext接口org.springframework.context.ApplicationContext 还要有一个实现类org.springframework.context.support.FileSystemXmlApplicationContext   下面是用于测试的main方法 public static void main(String[] args) {

    String url = System.getProperty("user.dir");

    ApplicationContext context = new FileSystemXmlApplicationContext(url + "/com/yangsq/props/beans-config.xml");

    HelloBean helloBean = (HelloBean)context.getBean("helloBean");

    System.out.println("welcome " + helloBean.getName() +

       ", your number is " + helloBean.getNumber());

     System.out.println("now is " + helloBean.getDate());

}   这里说明以下读取配置文件,FileSystemXmlApplicationContext使用IO的方式读取配置文件,所以要给出完整的路径。   下面是工程层次图:

Spring学习笔记(二)----Constructor Injection or Setter Injection

  运行以下会的出如下结果  

Spring学习笔记(二)----Constructor Injection or Setter Injection

这就完成了一个Constructor Injection的应用实例。       下面我们把这个应用改为Setter Injection的形式,很简单,只需改动一下beans-config.xml,如下:   <?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" " http://www.springframework.org/dtd/spring-beans.dtd "> <beans>

   <bean id="helloBean" class="com.yangsq.spring.HelloBean">

      <property name="date">

          <bean class="java.util.Date"/>

      </property>

      <property name="name">

          <value>yangsq<value/>       </property>

      <property name="number">

          <value>123<value/>       </property>

   </bean>

</beans>   其中,每个property属性对应一个HelloBean属性,注意,name值一定要和HelloBean的属性名相同。   运行一下吧,结果与上面的相同(时间有些差别)。       Constructor Injection和Setter Injection的差别,在于前者在对象建立时就准备好了所有的资源,而后者是建立好后在使用setter方法进行设定。使用Constructor Injection的好处是在构造对象的同时一并完成依赖关系的建立。但是如果建立的关系很多,那么构造函数就会很丑。使用Setter方法就不会产生这样的烦恼,而且透过方法名可以很清楚的了解注入的对象。当然,使用Setter方法就不能保证在运行时依赖不被修改。不过,还是尽量使用Setter Injection,因为几乎所有的开发者都乐于这么做。

继续阅读