最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

09-Spring初級容器初始化:尋找標(biāo)簽解析的入口

2023-06-13 17:37 作者:儒猿課堂  | 我要投稿

開篇

? ? ? ?截止目前,我們依然處于applicationContext.xml加載和解析的這條路上,值的慶幸的是,我們對這個過程逐漸的明朗起來了。

? ? ? ?首先,我們將applicationContext.xml封裝為資源ClassPathResource,然后再通過EncodedResource和InputSource的進(jìn)一步封裝之后,交給DOM的API進(jìn)行解析并獲取xml對應(yīng)的Document。


? ? ? ?并且,我們也了解到,Spring在解析xml文件前還需要對xml文件進(jìn)行校驗(yàn),光是校驗(yàn)方式我們就了解了DTD和XSD這兩種,并且,我們還分析了不同的校驗(yàn)方式的判定方式,以及如何通過程序獲取相應(yīng)的聲明文件。


? ? ? ?確實(shí),Spring在這塊做的比較嚴(yán)謹(jǐn),也無愧于它是一款風(fēng)靡世界的框架,好了,現(xiàn)在對xml文件的校驗(yàn)環(huán)節(jié)結(jié)束之后,我們通過DOM的API也得到了xml的Document。

? ? ? ?接下來,我們沿著之前的位置,繼續(xù)來看下Spring是如何解析xml文件的吧,這一節(jié)主要分為以下幾個部分:

? ? ? ?1.首先沿著上一節(jié)的源碼,看下Document的解析是在什么位置開始的

? ? ? ?2.然后再來看下Spring中,具體是由哪個組件負(fù)責(zé)解析Document的,先找到解析的入口

? ? ? ?3.最后我們再來看下xml中,標(biāo)簽的解析都有哪些類型,并且是如何判定這些標(biāo)簽類型的

Document解析的入口

? ? ? ?這一節(jié),我們再回到之前doLoadBeanDefinitions方法中看下:

? ? ? ?可以看到,現(xiàn)在我們通過doLoadDocument方法已經(jīng)獲取到了xml對應(yīng)的Document對象。

? ? ? ?下一步,我們就要來看下Spring是如何解析Document的了,我們可以跟進(jìn)到registerBeanDefinitions方法中看下:

? ? ? ?可以看到,首先調(diào)用createBeanDefinitionDocumentReader方法,創(chuàng)建BeanDefinitionDocumentReader類型的對象documentReader。

? ? ? ?因?yàn)锽eanDefinitionDocumentReader只是一個接口,那documentReader具體是什么類型呢?我們到createBeanDefinitionDocumentReader方法中看下:

? ? ? ?很明顯,BeanUtils的instantiateClass方法就是通過documentReaderClass類來創(chuàng)建對象,那documentReaderClass類又是誰呢,我們繼續(xù)來看下:

? ? ? ?可以看到,原來documentReader的實(shí)際類型為DefaultBeanDefinitionDocumentReader。


? ? ? ?我們回到剛才registerBeanDefinitions方法的位置:

? ? ? ?創(chuàng)建完DefaultBeanDefinitionDocumentReader之后,下一步可以看到通過getRegistry方法進(jìn)一步調(diào)用getBeanDefinitionCount方法,其實(shí),方法的目的也就是看下之前Spring容器中已經(jīng)注冊了多少個bean了,方便registerBeanDefinitions方法最后返回本次注冊bean的數(shù)量。

? ? ? ?可以看到,接著就通過documentReader調(diào)用registerBeanDefinitions方法正式解析Document了,我們到方法registerBeanDefinitions中繼續(xù)來看下:

? ? ? ?發(fā)現(xiàn)這一步并沒有什么特別的地方,通過觀察我們可以發(fā)現(xiàn)在Spring源碼中,但凡你看到以do為方法名前綴的方法時,基本上就快接近核心邏輯了。

? ? ? ?可以看到,doc調(diào)用getDocumentElement獲取Document的文檔元素,我們可以理解為就是獲取applicationContext.xml中整個根標(biāo)簽也就是beans標(biāo)簽,然后將它傳入doRegisterBeanDefinitions方法中。


委托BeanDefinitionParserDelegate來解析

? ? ? ?可以想象到的是,在方法doRegisterBeanDefinitions中才會開始正式解析Document,所以,我們繼續(xù)到方法doRegisterBeanDefinitions中看下:

? ? ? ?在方法doRegisterBeanDefinitions方法中,首先,我們來看下成員變量delegate是什么,我們再到方法createDelegate中看下:

? ? ? ?可以看到,成員變量delegate的類型其實(shí)就是BeanDefinitionParserDelegate,從名稱上大概可以猜到,BeanDefinitionParserDelegate是解析Document并封裝BeanDefinition的一個代理類。


? ? ? ?我們再回到doRegisterBeanDefinitions方法看下:

? ? ? ?前面一些瑣碎的代碼無關(guān)緊要,但是,最后這三個方法看起來比較關(guān)鍵,我們挨個來看下:

? ? ? ?簡單看了下發(fā)現(xiàn),方法preProcessXml和方法postProcessXml都是空實(shí)現(xiàn)。

? ? ? ?其實(shí),我們從方法preProcessXml和postProcessXml被protected關(guān)鍵字修飾的這個細(xì)節(jié),大概可以推斷出這兩個方法應(yīng)該是留給繼承DefaultBeanDefinitionDocumentReader的子類去拓展的。

? ? ? ?現(xiàn)在,我們的目標(biāo)就很清晰了,直接到parseBeanDefinitions方法中看下吧:

? ? ? ?可以看到,Document元素的解析就全權(quán)交給BeanDefinitionParserDelegate來處理了。


默認(rèn)標(biāo)簽和自定義標(biāo)簽的判定

? ? ? ?首先delegate調(diào)用方法isDefaultNamespace,來判斷當(dāng)前解析的元素root是否是默認(rèn)的命名空間,什么意思呢?我們到方法isDefaultNamespace中看下:

? ? ? ?可以看到在方法isDefaultNamespace中,會繼續(xù)調(diào)用isDefaultNamespace方法,在isDefaultNamespace方法中判定的方式也比較簡單,只要namespaceUri為空或namespaceUri為:

http://www.springframework.org/schema/beans

? ? ? ?只要滿足以上任意一個條件,就認(rèn)為當(dāng)前解析的標(biāo)簽為默認(rèn)標(biāo)簽,否則具有其他類型的namespaceUri標(biāo)簽都會被認(rèn)為是自定義標(biāo)簽。

? ? ? ?Spring自定義標(biāo)簽是相對于默認(rèn)標(biāo)簽<bean/>而言的,比如Spring內(nèi)部也自定義了很多自定義標(biāo)簽,如<context:component-scan/> 、<tx:annotation-driven/>等。


? ? ? ?那namespaceUri是從哪里來的呢?不知道大家還記得不,我們來看下applicationContext.xml文件:

? ? ? ?也就是說,當(dāng)我們解析bean標(biāo)簽時,bean標(biāo)簽對應(yīng)的命名空間的URI即namespaceURI其實(shí)就是:http://www.springframework.org/schema/beans,來自于圖中beans標(biāo)簽上的xmlns屬性。

? ? ? ?同時,我們到方法getNamespaceURI中看下:

? ? ? ?可以看到參數(shù)namespaceUri的值是通過方法getNamesapceURI獲取的,命名空間的URI其實(shí)就是從Node中獲取的一個屬性,而Node就是DOM API中表示具體標(biāo)簽的一個節(jié)點(diǎn),比如每個bean標(biāo)簽中的信息也會封裝在一個Node中。


? ? ? ?我們再回到parseBeanDefinitions方法中:

? ? ? ?因?yàn)槲覀冊趚ml中配置的就是默認(rèn)的標(biāo)簽bean,所以,下一步我們就要進(jìn)入到解析標(biāo)簽的核心環(huán)節(jié)了,也就是parseDefaultElement方法,考慮到目前Spring基于注解開發(fā)用的比較多,所以,我們這里重點(diǎn)分析Spring中最核心的默認(rèn)標(biāo)簽。

? ? ? ?分析到了這里我們及時總結(jié)下,從XmlBeanFactory將資源Resource交給XmlBeanDefinitionReader開始,中間經(jīng)歷的幾次重要的任務(wù)委托,我們結(jié)合XmlBeanDefinitionReader的類繼承圖來看下:

? ? ? ?首先,XmlBeanDefinitionReader經(jīng)過Resource資源的各種封裝之后,將資源交給了DocumentLoader來處理,DocumentLoader負(fù)責(zé)將Resource加載成一個Document對象。


? ? ? ?然后,XmlBeanDefinitionReader又將Document的解析任務(wù)交給了BeanDefinitionDocumentReader來處理,BeanDefinitionDocumentReader的實(shí)現(xiàn)類DefaultBeanDefinitionDocumentReader,又將Document中的各種標(biāo)簽解析任務(wù),全權(quán)交給了BeanDefinitionParserDelegate來處理。


總結(jié)

? ? ? ?好了,今天的知識點(diǎn),我們就講到這里了,我們來總結(jié)一下吧。

? ? ? ?我們來梳理下目前Spring源碼分析的流程:

? ? ? ?這一節(jié),我們從解析Document開始,發(fā)現(xiàn)Document中的元素解析任務(wù)都交給BeanDefinitionParserDelegate來處理,并且,我們發(fā)現(xiàn)在Spring中標(biāo)簽的解析是分為默認(rèn)標(biāo)簽和自定義標(biāo)簽的,而且我們也已經(jīng)找到解析標(biāo)簽的入口了。

? ? ? ?下一節(jié),我們就順著Spring自定義標(biāo)簽解析的入口方法parseDefaultElement開始分析,看下Spring是如何解析各種各樣的標(biāo)簽的。


09-Spring初級容器初始化:尋找標(biāo)簽解析的入口的評論 (共 條)

分享到微博請遵守國家法律
泗洪县| 饶平县| 庆安县| 阳泉市| 时尚| 达拉特旗| 石屏县| 资中县| 县级市| 张掖市| 报价| 酉阳| 清水县| 灵寿县| 渝中区| 营山县| 嫩江县| 凌海市| 马公市| 嘉定区| 开封县| 娄底市| 凯里市| 筠连县| 松潘县| 南川市| 陵水| 河曲县| 鸡西市| 浦北县| 保山市| 隆子县| 陇川县| 廉江市| 和平县| 隆回县| 资溪县| 江阴市| 文安县| 台北市| 平塘县|