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

来源:互联网 发布:格式化工厂 mac 编辑:程序博客网 时间:2024/05/29 19:48
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的方式读取配置文件,所以要给出完整的路径。


运行以下会的出如下结果


这就完成了一个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,因为几乎所有的开发者都乐于这么做。


0 0
原创粉丝点击