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

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

07-Spring初級容器初始化:XML文件的校驗模式

2023-06-12 19:15 作者:儒猿課堂  | 我要投稿

開篇


上一節(jié),我們了解了一下Spring是如何解析xml文件的,其實也就是通過DOM方式來解析,但是解析的過程肯定不是像我們的案例中那么簡單。

比如說,xml配置文件是否按照規(guī)定的格式來配置呢?否則,你要是在xml文件中隨意配置的話,Spring在解析的時候肯定就會出錯。

所以這一節(jié),我們來看下Spring是如何對xml文件進行格式校驗的,主要有一下幾個部分:

1.在加載Document的同時,看下EntityResolver實際是什么數(shù)據(jù)類型

2.然后再了解下在Spring對xml文件的校驗都有哪些方式

3.最后來看下Spring中,分別是哪些組件來支持這些校驗方式的


EntityResolver的初始化


我們回到上節(jié)調(diào)用loadDocument方法的位置:

可以看到,在loadDocument方法中傳入了EntityResolver類型的參數(shù)entityResolver,我們繼續(xù)上一節(jié)的問題,也就是參數(shù)entityResolver到底是什么呢?


我們回過頭來到上一步方法doLoadDocument中,看下參數(shù)entityResolver是從哪里傳進來的:

可以看到,參數(shù)entityResolver其實是通過方法getEntityResolver創(chuàng)建的,我們到getEntityResolver方法中看下:

發(fā)現(xiàn)entityResolver果然是在getEntityResolver方法中初始化的,但是現(xiàn)在又有一個問題了,entityResolver的實際類型到底是ResourceEntityResolver還是DelegatingEntityResolver呢?


從代碼中可以看到,這就取決于getResourceLoader方法的返回結(jié)果resourceLoader是否為空,如果resourceLoader為空,entityResolver就初始化為ResourceEntityResolver,否則entityResolver就初始化為DelegatingEntityResolver。

當然,我們可以簡單調(diào)試下就知道它是否為空,但是,我們還是有必要分析下的,可以到getResourceLoader方法中看下:

可以看到直接就返回成員變量resourceLoader,現(xiàn)在問題在于resourceLoader是否為空呢?那我們就要看下成員變量resourceLoader到底是在哪里初始化的。

簡單看了下發(fā)現(xiàn),在成員變量resourceLoader所在類AbstractBeanDefinitionReader的構(gòu)造方法中,發(fā)現(xiàn)了resourceLoader初始化的痕跡:

那我們可以想一下,AbstractBeanDefinitionReader類是在什么時候初始化的呢?如果我們找到AbstractBeanDefinitionReader的初始化的位置,這樣的話或許我們就可以知道參數(shù)registry的類型了,進而可以知道成員變量resourceLoader的類型了。


仔細想了下之后發(fā)現(xiàn),AbstractBeanDefinitionReader會不會是XmlBeanDefinitionReader的父類呢?

雖然AbstractBeanDefinitionReader我們不是很熟悉,但是XmlBeanDefinitionReader我們前面可是看到過初始化的,大家還有印象嗎,我們來回憶一下:

可以看到,我們前面剛進入到XmlBeanFactory構(gòu)造方法中時,就會初始化XmlBeanDefinitionReader,并且將Resource的加載交給它處理了。

然后,我們一步步跟進到XmlBeanDefinitionReader的構(gòu)造方法中看下:

果然,我們剛才的猜想是正確的,AbstractBeanDefinitionReader其實就是XmlBeanDefinitionReader的父類,而resourceLoader正是在AbstractBeanDefinitionReader的構(gòu)造方法中被初始化的。

因為這里的參數(shù)registry,其實就是通過XmlBeanDefinitionReader通過構(gòu)造方法參數(shù)this傳進來的,而this其實就是指XmlBeanFactory,因為XmlBeanFactory是實現(xiàn)了接口BeanDefinitionRegistry的。

然后,我們繼續(xù)看到AbstractBeanDefinitionReader的構(gòu)造方法,現(xiàn)在我們可以很容易知道XmlBeanFactory并不是ResourceLoader的實例,所以resourceLoader的具體類型就是PathMatchingResourcePatternResolver。

我們再回到剛才的getEntityResolver方法:

不管怎么樣,現(xiàn)在我們已經(jīng)知道了成員變量resourceLoader并不為空,那成員變量entityResolver也可以確定是ResourceEntityResolver的類型了。

那下一個問題是,EntityResolver到底有什么作用呢?接下來,我們就有必要來了解下Spring配置文件的校驗方式了。


XML的校驗方式:DTD和XSD


相信早期使用Spring的xml文件方式開發(fā)過同學,有一點是比較迷惑的,那就是Spring xml配置文件上的那些網(wǎng)址是干什么的,我們來看下:

可以看到,在beans標簽中的這些屬性,如xmlns、xmlns:xsi、xsi:schemaLocation,都有比較多的一些網(wǎng)址。

其實Spring通過這些網(wǎng)址能下載到一些文件,比如spring-beans.xsd,而xml文件的組成不光是xml文件本身,而且還包括它的約束語言,比如spring-beans.xsd就是xml約束語言XSD所規(guī)定的聲明文件。

XSD翻譯成英文就是XML Schemas Definition,也就是XML模式的定義,通過XSD的聲明文件可以約束你在xml文件中不能隨便亂寫,以保證xml文件格式的正確性。

那XSD具體是如何約束的呢?我們剛也看到了,在beans標簽中的屬性xsi:schemaLocation里,有如下網(wǎng)址:

http://www.springframework.org/schema/beans/spring-beans.xsd

Spring在解析xml文件的時候就可以通過該網(wǎng)址,從網(wǎng)上下載到XSD的聲明文件spring-beans.xsd。

spring-beans.xsd在聲明文件中規(guī)定了關(guān)于bean標簽相關(guān)的一些約束操作,如果我們沒有按照正確的規(guī)則去寫的話,Spring對xml文件的校驗就會失敗,同時也無法保證xml文件的格式正確性,Spring當然也就沒必要繼續(xù)處理下去了。

除了XSD之外,Spring還支持另外一種約束語言,也就是DTD,DTD翻譯英文就是Document Type Definition,也就是文檔類型的定義,在xml文件中的定義就像這樣:

可以看到,DTD在xml文件中是通過額外的一段配置來體現(xiàn),當然,我們也可以注意到在DTD模式下也會配置相應的網(wǎng)址:

http://www.springframework.org/dtd/spring-beans.dtd

通過這樣網(wǎng)址,Spring會去下載對應的DTD的聲明文件spring-beans.dtd,以便來約束我們按照一定的格式來配置xml文件。

DTD和XSD的具體規(guī)則的細節(jié)我們這里不再深究,現(xiàn)在我們來思考一個問題,既然我們已經(jīng)在xml配置文件中給出了具體的XSD和DTD文件的下載網(wǎng)址了,那在實際的開發(fā)中會出現(xiàn)什么問題呢?

可能有的同學已經(jīng)想到了,那就是如果我們要運行一個基于Spring開發(fā)的應用程序,但是,程序在運行的時候一旦斷網(wǎng)了,就會導致Spring沒法從網(wǎng)上下載相應的DTD或XSD聲明文件,那xml文件是否符合我們預期的格式也就無從得知了,另外,如果網(wǎng)速不好的話也會影響我們程序的穩(wěn)定性,這是無法接受的。

所以,Spring的研發(fā)團隊也考慮到這個問題了,索性就把相應的DTD和XSD文件都放到Spring對應的jar包中,這樣的話當Spring程序運行的時候,只需要通過相應的代碼程序,從jar包中獲取相應的DTD或XSD聲明文件就可以了,就不需要那么費力的從網(wǎng)上下載了。


初始化DTD和XSD的解析器


那現(xiàn)在問題在于,我們?nèi)绾胃鶕?jù)xml文件中的配置,獲取到對應的DTD或XSD聲明文件呢?現(xiàn)在,我們就可以回答剛才哪個問題了,這件事就是EntityResolver干的了。

我們再回到剛才源碼分析的位置:

剛才我們看到,因為resourceLoader不為空,所以成員變量entityResolver被初始化為了ResourceEntityResolver類型,而ResourceEntityResolver就是從jar包中,獲取xml文件對應的DTD或XSD聲明文件的。

那ResourceEntityResolver是如何獲取的呢,我們繼續(xù)到ResourceEntityResolver的構(gòu)造方法中看下:

可以發(fā)現(xiàn),resourceLoader賦給了ResourceEntityResolver的成員變量resourceLoader,但是,ResourceEntityResolver的父類構(gòu)造方法中又干了些什么事呢,我們繼續(xù)看下:

看到這里大家應該就明白了,從類的名稱我們就可以推斷出,BeansDtdResolver就是用來獲取DTD聲明文件的解析器,而PluggableSchemaResolver是用來獲取XSD聲明文件的解析器。

總結(jié)


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


一張圖來梳理下當前的流程:

這一節(jié),我們看了一下EntityResolver類型的參數(shù)entityResolver初始化的過程,同時,也了解了Spring源碼中校驗xml文件的兩種方式也就是DTD和XSD,它們分別都有對應的聲明文件來規(guī)范和校驗xml的格式。

并且,我們也看到對于不同校驗類型的xml文件,Spring分別準備了不同的解析器去校驗它們,BeansDtdResolver負責獲取DTD的聲明文件,PluggableSchemaResolver負責獲取XSD的聲明文件。

下一節(jié),我們就來看下這兩種解析器,它們是如何獲取對應的聲明文件及如何獲取xml校驗類型的吧。


07-Spring初級容器初始化:XML文件的校驗模式的評論 (共 條)

分享到微博請遵守國家法律
灵山县| 钦州市| 潢川县| 莱阳市| 旌德县| 五家渠市| 邳州市| 扶风县| 浑源县| 钟山县| 万盛区| 金坛市| 唐河县| 始兴县| 崇明县| 长葛市| 拉萨市| 黄浦区| 横山县| 寿宁县| 荔波县| 鹿邑县| 微山县| 禄丰县| 澎湖县| 定西市| 阜宁县| 若尔盖县| 改则县| 汪清县| 大厂| 宜宾县| 綦江县| 宜城市| 大连市| 治多县| 石河子市| 万安县| 峨山| 景洪市| 永仁县|