spring源碼分析1----讀xml文件

作者:shihuaping0918@163.com轉(zhuǎn)載請注明作者

spring是怎么讀取xml配置文件的,又是怎么把xml里的bean裝載進(jìn)去的呢,這就是本篇文章的內(nèi)容。配置讀取使用的類是ClassPathXmlApplicationContext,這個(gè)類的繼承層次如下:

可以看出層次還是比較多的,ClassPathXmlApplicationContext其實(shí)只是一個(gè)殼子,方便使用的時(shí)候傳遞一些參數(shù),其中就包括了xml文件的路徑,xml路徑可以有多個(gè),最終填充在configResources或者調(diào)用setConfigLocations——傳遞到了AbstractRefreshableApplicationContext。這個(gè)類只有一個(gè)動(dòng)作,就是refresh。這個(gè)refresh是在AbstractApplicationContext里實(shí)現(xiàn)的,這個(gè)方法很復(fù)雜,涉及的內(nèi)容比較多。后面再慢慢講。不論路徑怎么傳遞,反正都是要調(diào)用refresh的。

繼續(xù)分析之前,先說明一下各個(gè)類到底是干什么的,有個(gè)大概印象,這樣講到某些功能的時(shí)候,可以大概推測是在哪個(gè)類里。ClassPathXmlApplicationContext是個(gè)配參數(shù)的類,方便用戶傳參。AbstractXmlApplicationContext實(shí)現(xiàn)的功能是讀xml文件。AbstractRefreshableConfigApplicationContext實(shí)現(xiàn)的是一些屬性配置功能,比如xml文件路徑什么的。AbstractApplicationContext是具體干活的,承擔(dān)的任務(wù)非常重。再往下就沒什么可講的了。這樣很好的實(shí)現(xiàn)了分離,每一層做自己的事,通用的功能剝離出去了。但是讀代碼的時(shí)候,就很不順利了,在印象沒有建立起來之前,感覺是在繞迷宮。

AbstractRefreshableConfigApplicationContext這個(gè)類,有一個(gè)方法

public void setConfigLocations(@Nullable String... locations) {
     if (locations != null) {
         Assert.noNullElements(locations, "Config locations must not be null");
         this.configLocations = new String[locations.length];
         for (int i = 0; i < locations.length; i++) {
              this.configLocations[i] = resolvePath(locations[i]).trim();
        }
    }
   else {
        this.configLocations = null;
    }
}

這個(gè)setConfigLocations在ClassPathXmlApplicationContext中被調(diào)用過,實(shí)際上就是配一下xml文件的路徑。xml文件路徑的傳出是在

@Nullable
protected String[] getConfigLocations() {
    return (this.configLocations != null ? this.configLocations : getDefaultConfigLocations());
}

這個(gè)getConfigLocations是在AbstractXmlApplicationContext中調(diào)用的

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
   Resource[] configResources = getConfigResources();
    if (configResources != null) {
        reader.loadBeanDefinitions(configResources);
    }
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
         reader.loadBeanDefinitions(configLocations);
    }
}

注意看AbstractXmlApplicationContext這個(gè)loadBeanDefinitions方法,它首先是調(diào)用了getConfigResources,這個(gè)方法實(shí)際是在ClassPathXmlApplicationContext中實(shí)現(xiàn)的。而后一個(gè)getConfigLocations是在AbstractRefreshableConfigApplicationContext中實(shí)現(xiàn)的。到了這里ClassPathXmlApplicationContext和AbstractRefreshableConfigApplicationContext就算分析完成了。

下面再看看AbstractXmlApplicationContext,這個(gè)類前面就講過了,是加載xml用的,而它要加載的xml文件路徑是來自于ClassPathXmlApplicationContext和AbstractRefreshableConfigApplicationContext。下面看看加載xml的代碼。

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    Resource[] configResources = getConfigResources();
    if (configResources != null) {
        reader.loadBeanDefinitions(configResources);
    }
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
        reader.loadBeanDefinitions(configLocations);
    }
}

這段代碼之前已經(jīng)貼過了,可以看到,工作都是由reader這個(gè)參數(shù)來完成的。到了這里,休息一下,下一篇繼續(xù)尋找這個(gè)reader是哪來的,它做了什么。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容