Spring配置文件解析之BeanDefinitionReader詳解
BeanDefinitionReader
Spring配置文件的解析是通過(guò)BeanDefinitionReader來(lái)實(shí)現(xiàn)的,其實(shí)了解BeanDefinitionReader實(shí)現(xiàn)的機(jī)制就會(huì)發(fā)現(xiàn),其只是將ApplicationContext.xml配置文件解析成Document對(duì)象,真正對(duì)xml中元素解析的類(lèi)是在BeanDefinitionDocumentReader的實(shí)現(xiàn)類(lèi)中來(lái)完成的,接下來(lái)我們也會(huì)對(duì)它進(jìn)行介紹。
對(duì)ApplicationContext.xml中開(kāi)始解析的方法是loadBeanDefinitions
AbstractBeanDefinitionReader的loadBeanDefinitions中會(huì)對(duì)ApplicationContext.xml進(jìn)行解析
@Override public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException { Assert.notNull(locations, "Location array must not be null"); int counter = 0; for (String location : locations) { counter += loadBeanDefinitions(location); } return counter; }
@Override public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException { return loadBeanDefinitions(location, null); }
loadBeanDefinitions中會(huì)根據(jù)文件地址來(lái)進(jìn)行解析操作:
public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException { //判斷資源地址類(lèi)型 if (resourceLoader instanceof ResourcePatternResolver) { // Resource pattern matching available. try { Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location); //在子類(lèi)的loadBeanDefinitions進(jìn)行解析操作 int loadCount = loadBeanDefinitions(resources); if (actualResources != null) { for (Resource resource : resources) { actualResources.add(resource); } } if (logger.isDebugEnabled()) { logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]"); } return loadCount; } catch (IOException ex) { throw new BeanDefinitionStoreException( "Could not resolve bean definition resource pattern [" + location + "]", ex); } } else { // Can only load single resources by absolute URL. Resource resource = resourceLoader.getResource(location); //在子類(lèi)的loadBeanDefinitions進(jìn)行解析操作 int loadCount = loadBeanDefinitions(resource); if (actualResources != null) { actualResources.add(resource); } if (logger.isDebugEnabled()) { logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]"); } return loadCount; } }
loadBeanDefinitions是在子類(lèi)XmlBeanDefinitionReader中實(shí)現(xiàn)
@Override public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException { return loadBeanDefinitions(new EncodedResource(resource)); }
doLoadBeanDefinitions會(huì)將文件地址解析為數(shù)據(jù)流,然后解析數(shù)據(jù)流
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { .......... try { //從xml文件中獲取流 InputStream inputStream = encodedResource.getResource().getInputStream(); try { InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } //解析文件流 return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } finally { inputStream.close(); } } ....... }
doLoadBeanDefinitions中會(huì)將文件流解析成Document對(duì)象
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { Document doc = doLoadDocument(inputSource, resource); return registerBeanDefinitions(doc, resource); } ..... }
registerBeanDefinitions中會(huì)創(chuàng)建BeanDefinitionDocumentReader來(lái)對(duì)Document進(jìn)行解析,對(duì)Spring配置文件中的元素進(jìn)行解析處理。
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { //創(chuàng)建Document解析處理器 BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); int countBefore = getRegistry().getBeanDefinitionCount(); //在BeanDefinitionDocumentReader中解析xml中配置的元素 documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); return getRegistry().getBeanDefinitionCount() - countBefore; }
總結(jié)
簡(jiǎn)單來(lái)說(shuō)BeanDefinitionReader所做的處理操作是將配置的ApplicationContext.xml解析成為Document對(duì)象,接下來(lái)會(huì)有 BeanDefinitionDocumentReader來(lái)對(duì)Document進(jìn)行解析。
到此這篇關(guān)于Spring配置文件解析之BeanDefinitionReader詳解的文章就介紹到這了,更多相關(guān)Spring的BeanDefinitionReader內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot文件上傳(本地存儲(chǔ))回顯前端操作方法
這篇文章主要介紹了SpringBoot文件上傳(本地存儲(chǔ))回顯前端操作方法的相關(guān)資料,文中講解了文件上傳的基本原理,包括前端調(diào)用后端接口上傳文件,后端返回文件路徑給前端,前端通過(guò)路徑訪問(wèn)圖片,需要的朋友可以參考下2024-11-11Java static關(guān)鍵字詳細(xì)介紹與用法總結(jié)
這篇文章主要介紹了Java中static關(guān)鍵字的作用和用法詳細(xì)介紹,主要講了靜態(tài)方法、靜態(tài)變量、靜態(tài)類(lèi)、static和final一塊用等內(nèi)容。需要的朋友可以參考下2017-04-04mybatis-xml映射文件及mybatis動(dòng)態(tài)sql詳解
XML映射文件的名稱(chēng)與Mapper接口名稱(chēng)一致,并且將XML映射文件和Mapper接口放置在相同包下(同包同名),這篇文章主要介紹了mybatis-xml映射文件及mybatis動(dòng)態(tài)sql的相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧2024-12-12使用SpringBoot根據(jù)配置注入接口的不同實(shí)現(xiàn)類(lèi)(代碼演示)
使用springboot開(kāi)發(fā)時(shí)經(jīng)常用到@Autowired和@Resource進(jìn)行依賴(lài)注入,但是當(dāng)我們一個(gè)接口對(duì)應(yīng)多個(gè)不同的實(shí)現(xiàn)類(lèi)的時(shí)候如果不進(jìn)行一下配置項(xiàng)目啟動(dòng)時(shí)就會(huì)報(bào)錯(cuò),那么怎么根據(jù)不同的需求注入不同的類(lèi)型呢,感興趣的朋友一起看看吧2022-06-06使用自定義參數(shù)解析器同一個(gè)參數(shù)支持多種Content-Type
這篇文章主要介紹了使用自定義參數(shù)解析器同一個(gè)參數(shù)支持多種Content-Type的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08深入理解JVM之Java對(duì)象的創(chuàng)建、內(nèi)存布局、訪問(wèn)定位詳解
這篇文章主要介紹了深入理解JVM之Java對(duì)象的創(chuàng)建、內(nèi)存布局、訪問(wèn)定位,結(jié)合實(shí)例形式詳細(xì)分析了Java對(duì)象的創(chuàng)建、內(nèi)存布局、訪問(wèn)定位相關(guān)概念、原理、操作技巧與注意事項(xiàng),需要的朋友可以參考下2019-09-09java HashMap通過(guò)value反查key的代碼示例
本文講解了java HashMap通過(guò)value反查key的方法,直接提供代碼供大家參考使用2013-11-11