1. 程式人生 > >Spring核心類和原理分析

Spring核心類和原理分析



spring 的骨架

spring 的骨架,也是spring 的核心包。主要包含三個內容 1.context:spring 的上線文-------導演 2.core:spring的核心包,主要包括spring所以用到的工具-------道具 3.beans:spring的bean例項 -------演員


導演負責安排演出,演員負責按照導演的指示來演出,演出過程中需要使用道具。

我想大家看完這些圖片之後就明白大致的包關係了。

spring包結構


大家看到相應包內容。 core包側重於幫助類,操作工具,beans包更側重於bean例項的描述。context更側重全域性控制,功能衍生。 下面我們就針對context和factory對類的關係繼續一個基本概括:

核心類之間的關係

我們先來看下bean包下的beanfactory類,以及抽象類等。
可以看到在介面的實現泛化的過程中,每一個介面在繼承父介面的同時,也繼承了父介面的一些方法。這就可以看出面向介面變成微妙之處。

BeanFactory【所有BeanFactory的父類】


可以看到beanfactory中定義了一些基本方法,包括根據名稱獲取bean例項等。

HierarchicalBeanFactory【層次化的BeanFactory】


可以看到此介面實現了層次化,及獲取beanFactory的父容器

LisableBeanFactory列表式Beanfactory


可以看到為beanfactory設定了列表的功能,並且規劃瞭如何從列表中取出相應的方法的能力。

小結:

從上述類命名以及介面規劃可以看到,通過介面的不斷繼承,beanfactory被不斷的豐富抽象起來。層層細分之後,沒有個類都的職責都變的單一了,同時在擴充套件該的屬性時也變的更加方便。針對原始碼,最好的辦法還是根據名稱來,最方便。

context【上下線文】


可以看到到了context的初始化不同於beanfactory,可以側重於抽象型別,具體的方法實現。 裡面大部分方法使用了模板方法的設計模式,父類呼叫抽象方法,抽象方法在子類中實現,物件的獨立性。 主要分成三種context:XML,Annotation,Groovy針對三種形式。

registry【例項或者bean描述註冊器】


將初始化完成的bean註冊的容器中,針對單例來部分,快取單例例項。針對beanDefinition部分,快取bean描述。

Strategy【初始化策略】


兩種初始化策略 一種是簡單策略,一種是cgilib的策略,當時這裡使用的模式是策略模式。

context的初始化

  1. /** 
  2.  * 在parent下建立ClassPathXmlApplicaitonContext, 
  3.  * 從XML中讀取所有Bean定義. 
  4.  * @param configLocations 配置檔案路徑如c:\simpleContext.xml 
  5.  * @param refresh 是否需要自動重新整理context,refresh-->重新載入 
  6.  * 載入所有的bean定義,建立所有單例. 
  7.  * refresh為true的時候, 根據context來手工重新整理 
  8.  * @param parent the parent context 
  9.  * @throws BeansException if context creation failed 
  10.  * @see #refresh() 
  11.  */
  12. public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)  
  13.         throws BeansException {  
  14.     //初始化XmlApplicationContext
  15.     super(parent);  
  16.     //轉換配置檔案的路徑
  17.     setConfigLocations(configLocations);  
  18.     if (refresh) {  
  19.         //重新重新整理原有的context,這一篇的重點
  20.         refresh();  
  21.     }  
  22. }  

下面我們來看下AbstractApplicationContext.refresh()方法

  1. //載入或重新整理持久的配置,可能是xml檔案,properties檔案,或者關係型資料庫的概要。
  2. //做為一個啟動方法,如果初始化失敗將會銷燬已經建立好的單例,避免重複載入配置檔案。
  3. //換句話說,在執行這個方法之後,要不全部載入單例,要不都不載入
  4. publicvoid refresh() throws BeansException, IllegalStateException   
  5. {  
  6.     synchronized (this.startupShutdownMonitor)   
  7.     {  
  8.         // 初始化配置準備重新整理,驗證環境變數中的一些必選引數
  9.         prepareRefresh();  
  10.         // 告訴繼承類銷燬內部的factory建立新的factory的例項
  11.         // 初始化Bean例項
  12.         ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  
  13.         // 初始化beanFactroy的基本資訊,包括classloader,environment,忽略的註解等
  14.         prepareBeanFactory(beanFactory);  
  15.         try {  
  16.             // beanfactory內部的postProcess,可以理解為context中PostProcess的補充
  17.             beanFactory.postProcessBeanFactory(beanFactory);  
  18.             // 執行BeanFactoryPostProcessor(在beanFactory初始化過程中,bean初始化之前,修改beanfactory引數)、
  19.             // BeanDefinitionRegistryPostProcessor 其實也是繼承自BeanFactoryPostProcessor,
  20.             // 多了對BeanDefinitionRegistry的支援invokeBeanFactoryPostProcessors(beanFactory);
  21.             // 執行postProcess,那BeanPostProcessor是什麼呢,是為了在bean載入過程中修改bean的內容,
  22.             // 使用分的有兩個而方法Before、After分別對應初始化前和初始化後
  23.             registerBeanPostProcessors(beanFactory);  
  24.             // 初始化MessageSource,主要用作I18N本地化的內容
  25.             initMessageSource();  
  26.             // 初始化事件廣播ApplicationEventMulticaster,使用觀察者模式,對註冊的ApplicationEvent時間進行捕捉
  27.             initApplicationEventMulticaster();  
  28.             // 初始化特殊bean的方法
  29.             onRefresh();  
  30.             // 將所有ApplicationEventListener註冊到ApplicationEventMulticaster中
  31.             registerListeners();  
  32.             // 初始化所有不為lazy-init的bean,singleton例項
  33.             finishBeanFactoryInitialization(beanFactory);  
  34.             // 初始化lifecycle的bean並啟動(例如quartz的定時器等),如果開啟JMX則將ApplicationContext註冊到上面
  35.             finishRefresh();  
  36.         }  
  37.         catch (BeansException ex)   
  38.         {  
  39.             //銷燬已經建立單例
  40.             resources.destroyBeans();  
  41.             // 將context的狀態轉換為無效,標示初始化失敗
  42.             flag.cancelRefresh(ex);  
  43.             // 將異常傳播到呼叫者
  44.             throw ex;  
  45.         }  
  46.     }  
  47. }  
我們從時序圖來看啟動上述初始化(門面模式facade)

Spring初始化邏輯


可以看出主要針對beans context 還有core包。