零:認識BeanDefinitionjava
在面向對象程序設計中,咱們以"對象"來做爲問題空間與解空間中一對一映射關係的抽象。BeanDefinition類就是ioc容器中,對依賴反轉模式中管理的對象之間依賴關係的數據抽象,簡單來講:它抽象了spring對Bean的定義,用來管理基於spring的應用中的各類對象,以及對象之間的相互依賴關係。spring
一:BeanFactory接口清單app
BeanFactory定義了IOC容器的最基本形式,提供了IOC容器應該遵循的最基本服務契約。ide
getBean 方法是ioc容器的主要方法,能夠獲取ioc容器中管理的Beanspa
containsBean 判斷容器中是否含有指定name的bean設計
isSinglton 查詢指定name的bean是否爲單例模式code
isPrototype 查詢指定name的bean是否爲原型模式(多實例)xml
(isSinglton和isPrototype能夠在BeanDefinition中經過setScope來指定)對象
isTypeMatch 查詢指定name的Bean的class類型是否與特定的class類型匹配繼承
getType 查詢指定name的bean的class類型
getAliases 查詢指定name的Bean的全部別名(返回string[]),別名能夠經過BeanDefinition定義
-----------------------------------------------------------------------------------------------------
二:XmlBeanFactory
XmlBeanFactory是一個能夠讀取以xml文件方式定義的BeanDefinition的ioc容器
在xmlBeanFactory中初始化一個XmlBeanDefinitionReader對象,用它來處理以xml方式定義的BeanDefinition,xmlBeanFactory並不直接參與處理。
xmlBeanFactory的構造器中,咱們能夠看到Resourse對象,Resourse對象是spring用來封裝io操做的類,在此它爲xmlBeanFactory指定了XmlBeanDefinitionReader的信息來源。
XmlBeanFactory繼承自DefaultListableBeanFactory,spring把DefaultListableBeanFactory做爲一個默認的功能完整的ioc容器來使用,它實際包含了基本ioc容器所具備的重要功能。xmlBeanFactory在其基礎上擴展出了處理xml信息的方法。
從這個咱們能夠看到ioc容器使用的基本過程應該是:
1:建立ioc配置文件的抽象資源。(包含BeanDefinition)
2:建立一個BeanFactory。
3:建立一個載入BeanDefinition的讀取器(如XmlBeanDefinitionReader),並經過回調配置給BeanFactory。
4:講定義好的資源位置讀入配置信息,具體的解析過程由具體的讀取器來完成。完成載入和註冊bean信息後,就能夠經過ioc容器直接使用了。
-----------------------------------------------------------------------------------------------------
三:ApplicationContext
ApplicationContext在BeanFactory的基礎上添加了更多功能,能夠說是一個高級形態的ioc容器,也是咱們最經常使用的。
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {...}
ApplicationContext增長的特性:
1:支持不一樣的信息源。從上面代碼中能夠看到,ApplicationContext擴展了MessageSource接口,這些信息源的擴展功能能夠支持國際化的實現,爲開發多語言版本應用提供服務。
2:訪問資源。咱們能夠從不一樣的地方獲得Bean定義資源,尤爲是從不一樣的I/O途徑得到Bean的定義信息。這一特性體如今對ResourceLoader和Resource的支持上。(ApplicationContext接口的實現類都繼承了DefaultResourceLoader)
3:支持應用事件。繼承ApplicationEventPublisher接口,該接口在上下文中引入了事件機制,爲Bean的管理提供便利。
4:其餘附加的服務。
ApplicationContext容器的設計原理
咱們在研究applicationContext設計原理時,以實現類FileSystemXmlApplicationContext爲例。
public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext {...}
上圖能夠看到:FileSystemXmlApplicationContext中只包含了與它自身設計相關的兩項功能,而其餘功能都已經由他的父類AbstractXmlApplicationContext實現了。
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); } }
第一個功能:在FileSystemXmlApplicationContext的構造器中,調用了啓動ioc容器的refresh() 方法,這個方法牽扯到ioc容器啓動的一系列複雜動做,同時,對於不一樣的容器實現這些動做都是相似的,因此在基類(AbstractApplicationContext)中將他們封裝好,此處僅進行調用。
@Override protected Resource getResourceByPath(String path) { if (path != null && path.startsWith("/")) { path = path.substring(1); } return new FileSystemResource(path); }
另外一個功能:實現了從文件系統中加載xml的Bean定義資源。這部分是他設計的具體相關內容。經過他能夠爲讀取xml文件上保存的BeanDefinition作準備(僅是作準備,並不是直接處理,由於不一樣的應用上下文實現對應着不一樣的讀取beanDefinition方式),此處僅獲得FileSystemResourse定位資源。
總結:
1:頂層(相對頂層)接口定義通用契約
2:其餘分支接口對頂層契約進行擴展,
3:用抽象類實現接口,對接口方法進行部分實現(也可所有實現,根據需求判斷)。此時,若這個抽象類的具備多個子類,則能夠把子類間存在分歧的部分寫成抽象方法。而多個子類中相同的部分則集中由這個抽象類來進行實現。(若是僅僅只有一個子類,那麼並不須要抽象類來對接口進行過濾,能夠直接用一個類來實現接口,可是考慮到系統擴展的可能性,仍然建議這樣作。)
4:抽象類的子類,僅僅定義與其功能設計相關的部分,但並不對相關功能進行實現,實現功能的動做被分配到其餘執行者中。(由於可能會有多種不一樣的執行者)