Spring配置文件解析之BeanDefinitionDocumentReader詳解
Spring中的BeanDefinitionDocumentReader
上一篇Spring配置文件解析之BeanDefinitionReader詳解中我們已經(jīng)了解到BeanDefinitionReader已經(jīng)將Spring的xml配置文件解析成Document對(duì)象了,接下來(lái)的解析處理工作是在BeanDefinitionDocumentReader中對(duì)Document對(duì)象進(jìn)行解析工作了。
BeanDefinitionDocumentReader接口及其實(shí)現(xiàn)類:
BeanDefinitionDocumentReader提供的方法:
public interface BeanDefinitionDocumentReader { void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) throws BeanDefinitionStoreException; }
在 BeanDefinitionDocumentReader的實(shí)現(xiàn)類DefaultBeanDefinitionDocumentReader定義了對(duì)一些xml配置文件基本的元素的解析處理操作
在這里我們可能會(huì)有一個(gè)疑問(wèn),在Spring的xml配置文件中經(jīng)??吹降腶op等相關(guān)的配置是在什么地方解析處理的,其實(shí)他們都是通過(guò)NamespaceHandler實(shí)現(xiàn)類來(lái)完成的,接下來(lái)我們會(huì)對(duì)其進(jìn)行詳細(xì)的介紹。
在DefaultBeanDefinitionDocumentReader的registerBeanDefinitions方法中開(kāi)始對(duì)Document進(jìn)行解析。
@Override public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; logger.debug("Loading bean definitions"); Element root = doc.getDocumentElement(); doRegisterBeanDefinitions(root); }
在doRegisterBeanDefinitions中會(huì)創(chuàng)建BeanDefinitionParserDelegate來(lái)對(duì)Document進(jìn)行解析
protected void doRegisterBeanDefinitions(Element root) { BeanDefinitionParserDelegate parent = this.delegate; //創(chuàng)建BeanDefinitionParserDelegate,真正xml中各種元素的解析 this.delegate = createDelegate(getReaderContext(), root, parent); if (this.delegate.isDefaultNamespace(root)) { String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); if (StringUtils.hasText(profileSpec)) { String[] specifiedProfiles = StringUtils.tokenizeToStringArray( profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { if (logger.isInfoEnabled()) { logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + getReaderContext().getResource()); } return; } } } preProcessXml(root); parseBeanDefinitions(root, this.delegate); postProcessXml(root); this.delegate = parent; }
在parseBeanDefinitions會(huì)對(duì)Node進(jìn)行判斷,如果是上面配置默認(rèn)解析的spring標(biāo)簽,則會(huì)在DefaultBeanDefinitionDocumentReader中進(jìn)行解析,否則的話就需要 BeanDefinitionParserDelegate來(lái)委派找到解析處理器。
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { if (delegate.isDefaultNamespace(root)) { NodeList nl = root.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element) { Element ele = (Element) node; if (delegate.isDefaultNamespace(ele)) { //默認(rèn)的一些標(biāo)簽在DefaultBeanDefinitionDocumentReader進(jìn)行解析 parseDefaultElement(ele, delegate); } else { //如果不是默認(rèn)的就需要在通過(guò)委派模式來(lái)尋找解析處理器 delegate.parseCustomElement(ele); } } } } else { //如果不是默認(rèn)的就需要在通過(guò)委派模式來(lái)尋找解析處理器 delegate.parseCustomElement(root); } }
在parseDefaultElement中會(huì)對(duì)一些默認(rèn)的標(biāo)簽import,alias,bean,beans標(biāo)簽進(jìn)行處理
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { //解析import標(biāo)簽 if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } //解析alias標(biāo)簽 else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } //解析bean標(biāo)簽 else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); } //解析beans標(biāo)簽,就是進(jìn)行遞歸解析 else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // recurse doRegisterBeanDefinitions(ele); } }
對(duì)bean標(biāo)簽解析,最終還是在BeanDefinitionParserDelegate中對(duì)元素進(jìn)行處理解析生成BeanDefinitionHolder,其實(shí)bean元素的解析的結(jié)果是一個(gè)BeanDefinition對(duì)象,其包含了所有的bean的屬性設(shè)置,processBeanDefinition中的BeanDefinitionReaderUtils的處理結(jié)果是將BeanDefinition注冊(cè)到BeanFactory中。
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { //最終還是在BeanDefinitionParserDelegate中進(jìn)行元素解析 //BeanDefinitionHolder是對(duì)BeanDefinition的封裝,包括BeanDefinition,beanName,aliases BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { //處理的操作是將bean的元數(shù)據(jù)BeanDifinition注冊(cè)到BeanFactory中 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex); } // Send registration event. getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }
總結(jié)
BeanDefinitionDocumentReader中也沒(méi)有對(duì)xml中的bean元素進(jìn)行處理操作,其真正的處理操作是在BeanDefinitionParserDelegate中進(jìn)行處理的,都是在為他人做嫁衣。
到此這篇關(guān)于Spring配置文件解析之BeanDefinitionDocumentReader詳解的文章就介紹到這了,更多相關(guān)Spring中的BeanDefinitionDocumentReader內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Thymeleaf渲染網(wǎng)頁(yè)時(shí)中文亂碼的問(wèn)題及解決
這篇文章主要介紹了Thymeleaf渲染網(wǎng)頁(yè)時(shí)中文亂碼的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02SpringAOP事務(wù)配置語(yǔ)法及實(shí)現(xiàn)過(guò)程詳解
這篇文章主要介紹了SpringAOP事務(wù)配置語(yǔ)法及實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06Double.parseDouble()與Double.valueOf()的區(qū)別及說(shuō)明
這篇文章主要介紹了Double.parseDouble()與Double.valueOf()的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07MyBatisPlus中事務(wù)處理的實(shí)現(xiàn)
本文主要介紹了MyBatisPlus中事務(wù)處理的實(shí)現(xiàn),包括事務(wù)的開(kāi)啟、提交、回滾等操作,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07springboot2.0以上調(diào)度器配置線程池的實(shí)現(xiàn)
這篇文章主要介紹了springboot2.0以上調(diào)度器配置線程池的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12IDEA2022 提示更新 TKK失敗請(qǐng)檢查網(wǎng)絡(luò)連接的問(wèn)題
這篇文章主要介紹了IDEA2022 提示:更新 TKK 失敗,請(qǐng)檢查網(wǎng)絡(luò)連接,本文給大家分享解決方案,對(duì)idea2022提示更新TKK失敗感興趣的朋友跟隨小編一起看看吧2022-11-11