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,因為幾乎所有的開發者都樂于這麼做。