深入理解Spring4框架(二)——容器

ApplicationContext可以被看作Spring的容器,它是繼承自BeanFactory的。BeanFactory是訪問容器的根接口,提供了必要的配置框架和基礎功能,而ApplicationContext提供了更多的企業級功能和更加豐富的功能。

1 容器概覽

    org.springframework.context.ApplicationContext接口代表了SpringIoC容器,它用於實例化、配置和組合bean。通過讀取配置元數據,容器就能獲取到實例化、配置和組合對象的指令。XML、註解或Java代碼中可以存在配置元數據。

    Spring提供了幾種“開箱即用”的ApplicationContext接口實現。在單獨的應用程序中,創建一個ClassPathXmlApplicatlionContext或FileSystemXmlApplicationContext的實例是很普遍的。不過,在大部分應用場景中,不需要顯式地實例化一個或多個IoC實例。

    應用系統的類和配置元數據是結合在一起的,所以在ApplicationContext創建和初始化之後,應用系統就已經配置完畢且可以執行了。

2 配置元數據

    IoC容器採用配置元數據的方式。這種配置元數據表明了容器需要如何實例化、配置和組織對象。

    Spring配置至少包含一個bean定義。由基於XML的配置元數據可知,頂層<beans><beans/>中配置的即爲bean元素。Java配置通常在一個類中使用@Bean註解方法。

    這些根據實際對象定義的bean組成了應用程序。特別是在定義服務層對象、數據訪問層對象(DAO)、表現層對象(比如Struts的Action實例)等時候。

    下面的例子說明了一個基於XML配置元數據的基礎構造。

[xml] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.         http://www.springframework.org/schema/beans/spring-beans.xsd">  
  6.     <bean id="..." class="...">  
  7.         <!—屬性和配置 -->  
  8.     </bean>  
  9.     <bean id="..." class="...">  
  10.         <!—屬性和配置 -->  
  11.     </bean>  
  12.     <!—更多的bean定義-->  
  13. </beans>  

    id屬性是一個用來識別各個bean定義的字符串。class屬性定義了bean的類型,而且使用類名的全稱。id屬性的值引用的是對象。

3 容器的實例化

    Spring容器的實例化過程很直接,傳遞給ApplicationContext構造器的參數即爲配置元數據相關資源的路徑。

    ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});

    下面的例子即爲服務層對象services.xml配置文件:

[xml] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.         http://www.springframework.org/schema/beans/spring-beans.xsd">  
  6.     <!-- services -->  
  7.     <bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">  
  8.         <property name="accountDao" ref="accountDao"/>  
  9.         <property name="itemDao" ref="itemDao"/>  
  10.         <!—其它屬性和配置 -->  
  11.     </bean>  
  12.     <!—更多bean定義 -->  
  13. </beans>  

    下面即爲數據訪問對象daos.xml配置文件:

[xml] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.         http://www.springframework.org/schema/beans/spring-beans.xsd">  
  6.     <bean id="accountDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">  
  7.         <!—其它屬性和配置-->  
  8.     </bean>  
  9.     <bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">  
  10.         <!--其它屬性和配置-->  
  11.     </bean>  
  12.     <!—更多bean定義 -->  
  13. </beans>  

    在前述例子中,服務層包含類PetStoreServiceImpl,以及兩個數據訪問對象JpaAccountDao和JpaItemDao。name屬性表示bean的名稱,ref屬性表示引用另一個bean的名字。id和ref的關係即爲依賴關係。

    在一個龐大的系統中,如果將所有的bean定義存放在一個xml文件中,那麼維護起來將是一場噩夢。Spring提供了一種方式可以解決這個問題,即將不同業務層的配置文件放到不同的xml文件中,然後在一個xml文件中引入其它所有的配置文件。main.xml示例如下:

[xml] view plain copy
  1. <beans>  
  2.     <import resource="services.xml"/>  
  3.     <import resource="resources/messageSource.xml"/>  
  4.     <import resource="/resources/themeSource.xml"/>  
  5.     <bean id="bean1" class="..."/>  
  6.     <bean id="bean2" class="..."/>  
  7. </beans>  

    這個例子中,從三個文件裏引入了外部bean定義:services.xml,messageSource.xml和themeSource.xml。所有的路徑都是相對於main.xml的,因此services.xml必須與main.xml在相同路徑下,而其它兩個xml文件所在的文件夾resources路徑必須與main.xml相同。可見,前面的那一個斜槓被忽略了,因爲這裏必須是相對路徑,最好不要在路徑前面加上斜槓。

4 容器的使用

    ApplicationContext是一個高級工廠接口,它維護着不同的bean及其依賴的註冊。使用T getBean(String name, Class<T> requiredType)可以查詢到已實例化的bean。可以通過ApplicationContext來讀取和訪問定義的bean。

[java] view plain copy
  1. // 創建和配置bean  
  2. ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml""daos.xml"});  
  3. // 查詢配置的實例  
  4. PetStoreService service = context.getBean("petStore", PetStoreService.class);  
  5. // 使用配置的實例  
  6. List<String> userList = service.getUsernameList();  

    getBean用來查詢bean實例,ApplicationContext還有其它查詢bean實例的方法,理想情況下你不會用到它們。實際上,應用代碼中不應該有getBean方法,這樣就不用依賴Spring的API,比如Spring與Web框架的集成就提供了相應的依賴注入,而不需要顯式地去調用getBean方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章