天天看點

(1.0)Spring的IoC容器之BeanFactory

第4章 Spring的IoC容器之BeanFactory

本章内容

擁有BeanFactory之後的生活

BeanFactory的對象注冊與依賴綁定方式

BeanFactory的XML之旅

容器背後的秘密

我們前面說過,Spring的IoC容器是一個IoC Service Provider,但是,這隻是它被冠以IoC之名的部分原因,我們不能忽略的是"容器"。Spring的IoC容器是一個提供IoC支援的輕量級容器,除了基本的IoC支援,它作為輕量級容器還提供了IoC之外的支援。如在Spring的IoC容器之上,Spring還提供了相應的AOP架構支援、企業級服務內建等服務。Spring的IoC容器和IoC Service Provider所提供的服務之間存在一定的交集,二者的關系如圖4-1所示。

(1.0)Spring的IoC容器之BeanFactory
圖4-1 Spring的IoC容器和IoC Service Provider之間的關系

注意 本章将主要關注Spring的IoC容器提供的IoC相關支援以及衍生的部分進階特性。而IoC容器提供的其他服務将在後繼章節中陸續闡述。

Spring提供了兩種容器類型:BeanFactory和ApplicationContext。

BeanFactory。基礎類型IoC容器,提供完整的IoC服務支援。如果沒有特殊指定,預設采用延遲初始化政策(lazy-load)。隻有當用戶端對象需要通路容器中的某個受管對象的時候,才對該受管對象進行初始化以及依賴注入操作。是以,相對來說,容器啟動初期速度較快,所需要的資源有限。對于資源有限,并且功能要求不是很嚴格的場景,BeanFactory是比較合适的IoC容器選擇。

ApplicationContext。ApplicationContext在BeanFactory的基礎上建構,是相對比較進階的容器實作,除了擁有BeanFactory的所有支援,ApplicationContext還提供了其他進階特性,比如事件釋出、國際化資訊支援等,這些會在後面詳述。ApplicationContext所管理的對象,在該類型容器啟動之後,預設全部初始化并綁定完成。是以,相對于BeanFactory來說,ApplicationContext要求更多的系統資源,同時,因為在啟動時就完成所有初始化,容器啟動時間較之BeanFactory也會長一些。在那些系統資源充足,并且要求更多功能的場景中,ApplicationContext類型的容器是比較合适的選擇。

通過圖4-2,我們可以對BeanFactory和ApplicationContext之間的關系有一個更清晰的認識。

(1.0)Spring的IoC容器之BeanFactory
(點選檢視大圖)圖4-2 BeanFactory和ApplicationContext繼承關系

注意 ApplicationContext間接繼承自BeanFactory,是以說它是建構于BeanFactory之上的IoC容器。此外,你應該注意到了,ApplicationContext還繼承了其他三個接口,它們之間的關系,我們将在第5章中詳細說明。

另外,在沒有特殊指明的情況下,以BeanFactory為中心所講述的内容同樣适用于Applica- tionContext,這一點需要明确一下,二者有差别的地方會在合适的位置給出解釋。

BeanFactory,顧名思義,就是生産Bean的工廠。當然,嚴格來說,這個"生産過程"可能不像說起來那麼簡單。既然Spring架構提倡使用POJO,那麼把每個業務對象看作一個JavaBean對象,或許更容易了解為什麼Spring的IoC基本容器會起這麼一個名字。作為Spring提供的基本的IoC容器,BeanFactory可以完成作為IoC Service Provider的所有職責,包括業務對象的注冊和對象間依賴關系的綁定。

BeanFactory就像一個汽車生産廠。你從其他汽車零件廠商或者自己的零件生産部門取得汽車零件送入這個汽車生産廠,最後,隻需要從生産線的終點取得成品汽車就可以了。相似地,将應用所需的所有業務對象交給BeanFactory之後,剩下要做的,就是直接從BeanFactory取得最終組裝完成并且可用的對象。至于這個最終業務對象如何組裝,你不需要關心,BeanFactory會幫你搞定。

是以,對于用戶端來說,與BeanFactory打交道其實很簡單。最基本地,BeanFactory肯定會公開一個取得組裝完成的對象的方法接口,就像代碼清單4-1中真正的BeanFactory的定義所展示的那樣。

代碼清單4-1 BeanFactory的定義

  1. public interface BeanFactory {  
  2.     String FACTORY_BEAN_PREFIX = "&";  
  3.     Object getBean(String name) throws BeansException;  
  4.     Object getBean(String name, Class requiredType)  throws BeansException;  
  5.     /**  
  6.      * @since 2.5  
  7.      */ 
  8.     Object getBean(String name, Object[] args)  throws BeansException;  
  9.     boolean containsBean(String name);  
  10.     boolean isSingleton(String name) throws  NoSuchBeanDefinitionException;  
  11.     /**  
  12.      * @since 2.0.3  
  13.      */ 
  14.     boolean isPrototype(String name) throws  NoSuchBeanDefinitionException;  
  15.     /**  
  16.      * @since 2.0.1  
  17.      */ 
  18.     boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException;  
  19.     Class getType(String name) throws NoSuchBeanDefinitionException;  
  20.     String[] getAliases(String name);  

上面代碼中的方法基本上都是查詢相關的方法,例如,取得某個對象的方法(getBean)、查詢某個對象是否存在于容器中的方法(containsBean),或者取得某個bean的狀态或者類型的方法等。因為通常情況下,對于獨立的應用程式,隻有主入口類才會跟容器的API直接耦合。

繼續閱讀