Spring3.1.0實現原理分析(三).配置數據

      今天我想談一下,Spring從哪裏獲取配置數據? 配置數據做什麼用處? 如何存儲和訪問配置數據?就像一輛汽車,開之前總得先加油吧,不然何如工作呢。


1.  配置數據有哪些,何時加載,其作用是什麼。

       我覺得Spring的數據源至少可分爲兩類,JDK系統數據和用戶配置數據。jdk系統數據具體是指System#getProperties()方法返回值和System#getenv()方法返回值。用戶配置數據其一是使用<context:property-placeholder location="..." />指定的資源文件,最常見的場景就是在這個資源文件中配置數據庫的用戶名、密碼等。用戶配置數據還包括定義bean的資源文件,在Spring的初始化過程中會解析資源文件獲取Bean定義對象註冊到Bean工廠中。

       JDK系統配置數據是先於用戶配置數據加載的,在ApplicationContext的構造函數中即被加載,如此早加載是因爲可用它來解析用戶指定的資源文件路徑中可能存在的佔位符。Bean定義資源文件而後加載,最後在容器後處理器中加載<context:property-placeholder location=""/>指定的資源文件,然後使用它來解析Bean定義中的佔位符,比如你可能在Bean定義中使用${jdcb.uername}這個表達式代表數據庫用戶名。也就是說在實例化Bean對象前,Bean定義中的佔位符已經被替換成實際值,但是Bean定義中的Spel表達式尚未被解析。


2.  如何加載、存儲和訪問JDK系統配置數據

       Spring所有的一切是從創建ApplicationContext(以下簡稱AC)開始的,而AC的構造函數中第一個步驟是創建“基於路徑匹配的資源模式解析器”,這個類的作用是加載資源文件;第二個步驟就是創建“標準環境對象”。   

       在標準環境對象的構造函數中,它會調用JDK系統方法System#getProperties()和System#getenv(),兩者的返回值分別是“Properties”和“ Map<String,String>”,是兩種不同類型的對象。爲了使用統一的方式訪問它們,Spring會把它們包裝成屬性源對象(PropertySource),然後添加到自身持有的屬性源集對象(PropertySources)中,再通過屬性解析器對象(PropertyResolver)訪問屬性源對象。三者之間的關係可以用下圖來表述,

  

       標準環境對象還有幾個派生類,如標準Servlet環境對象(StandardServletEnvironment),這個類在超類把System#getProperties()和System#getenv()轉換成屬性源對象的基礎上,還會把ServletConfig#servletConfigInitParams()和servletConfig#servletContextInitParams()包裝成屬性源對象。這裏有個很有意思的處理方式,標準Servlet環境對象並沒有獲取真正的servletConfigInitParams和servletContextInitParams,僅僅只是兩個存根屬性源對象,然後由抽象可刷新Web容器把存根替換成真實對象,大概是爲了避免標準Servlet環境對象對Web對象有依賴


3.  如何加載用戶配置數據

     如果用戶在Spring配置文件中使用<context:property-placeholder location="..." />指定了資源文件路徑的話,Spring會自動註冊一個容器後處理器,在3.1版本中這個類是“PropertySourcesPlaceholderConfigurer”,該對象持有標準環境對象,處理具體步驟如下:

a. 首先加載用戶配置的資源文件,通過資源加載器(ResourceLoader)實現該功能,上面也說到過,AC構造函數函數中的第一步就是創建資源加載器, 通過它把資源文件轉換成資源對象(Resource),然後把資源對象轉換成屬性集對象(java系統類),再把屬性集合對象包裝成屬性源對象(PropertySource)

b. 合併標準環境對象的屬性源對象和用戶配置數據的屬性源對象,默認用戶配置屬性源對象優先級高。

c. 創建解析器,解析bean定義中的佔位符。 


好了,先寫到這裏。之所以討論配置數據,是因爲想搞清楚驅動Spring工作的能源是從哪來的,分別是哪些能源。

總結,能源有兩部分,一部分是系統環境的,一部分是用戶配置的,Spring會把所有的能源包裝成屬性源對象,然後通過屬性解析器獲取其中數據。


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