日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Spring通過(guò)<import>標(biāo)簽導(dǎo)入外部配置文件

瀏覽:33日期:2023-07-07 15:17:21
目錄示例原理DefaultBeanDefinitionDocumentReaderparseDefaultElementimportBeanDefinitionResource總結(jié)示例

我們先來(lái)看下配置文件是怎么導(dǎo)入外部配置文件的?先定義一個(gè)spring-import配置文件如下:

<?xml version='1.0' encoding='UTF-8'?><beans xmlns='http://www.springframework.org/schema/beans' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd'> <import resource='spring-config.xml'/> <bean class='com.john.aop.Person'> </bean></beans>

我們看到里面定義了一個(gè)標(biāo)簽并用屬性resource聲明了導(dǎo)入的資源文件為spring-config.xml。我們?cè)賮?lái)看下spring-config.xml配置文件是怎樣的:

<?xml version='1.0' encoding='UTF-8'?><beans xmlns='http://www.springframework.org/schema/beans' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd'> <bean class='com.john.aop.Person'> <property name='firstName' value='john'/> <property name='lastName' value='wonder'/> </bean> <bean abstract='true' > <property name='country' value='中國(guó)'/> <property name='gender' value='女'/> </bean></beans>

然后我們可以實(shí)例化一個(gè)BeanFactory來(lái)加載spring-import這個(gè)配置文件了。

public static void main(String[] args) { ApplicationContext context=new ClassPathXmlApplicationContext('spring-import.xml'); Person outerPerson=(Person)context.getBean('outerPerson'); System.out.println(outerPerson);}

如果沒(méi)問(wèn)題的話,我們可以獲取到outerPerson這個(gè)bean并打印了。

Person [0, john wonder]原理

我們來(lái)通過(guò)源碼分析下Spring是如何解析import標(biāo)簽并加載這個(gè)導(dǎo)入的配置文件的。首先我們到DefaultBeanDefinitionDocumentReader類中看下:

DefaultBeanDefinitionDocumentReader

我們可以看到類里面定義了一個(gè)public static final 的IMPORT_ELEMENT變量:

public static final String IMPORT_ELEMENT = 'import';

然后我們可以搜索下哪邊用到了這個(gè)變量,并且定位到parseDefaultElement函數(shù):

parseDefaultElement

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { //todo 對(duì) import 標(biāo)簽的解析 2020-11-17 if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); }}

這里就是我們要找的導(dǎo)入外部配置文件加載Bean定義的源代碼,我們?cè)僦攸c(diǎn)看下importBeanDefinitionResource函數(shù):

importBeanDefinitionResource

/** * Parse an 'import' element and load the bean definitions * from the given resource into the bean factory. */protected void importBeanDefinitionResource(Element ele) { //// 獲取 resource 的屬性值 String location = ele.getAttribute(RESOURCE_ATTRIBUTE); //// 為空,直接退出 if (!StringUtils.hasText(location)) { getReaderContext().error('Resource location must not be empty', ele); return; } // Resolve system properties: e.g. '${user.dir}' // // 解析系統(tǒng)屬性,格式如 :'${user.dir}' location = getReaderContext().getEnvironment().resolveRequiredPlaceholders(location); Set<Resource> actualResources = new LinkedHashSet<>(4); // Discover whether the location is an absolute or relative URI //// 判斷 location 是相對(duì)路徑還是絕對(duì)路徑 boolean absoluteLocation = false; try { //以 classpath*: 或者 classpath: 開頭為絕對(duì)路徑 absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute(); } catch (URISyntaxException ex) { // cannot convert to an URI, considering the location relative // unless it is the well-known Spring prefix 'classpath*:' } // Absolute or relative? //絕對(duì)路徑 也會(huì)調(diào)用loadBeanDefinitions if (absoluteLocation) { try { int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources); if (logger.isTraceEnabled()) { logger.trace('Imported ' + importCount + ' bean definitions from URL location [' + location + ']'); } } catch (BeanDefinitionStoreException ex) { getReaderContext().error( 'Failed to import bean definitions from URL location [' + location + ']', ele, ex); } } else { //如果是相對(duì)路徑,則先計(jì)算出絕對(duì)路徑得到 Resource,然后進(jìn)行解析 // No URL -> considering resource location as relative to the current file. try { int importCount; Resource relativeResource = getReaderContext().getResource().createRelative(location); //如果相對(duì)路徑 這個(gè)資源存在 那么就加載這個(gè)bean 定義 if (relativeResource.exists()) { importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource); actualResources.add(relativeResource); } else { String baseLocation = getReaderContext().getResource().getURL().toString(); //todo import節(jié)點(diǎn) 內(nèi)部會(huì)調(diào)用loadBeanDefinitions 操作 2020-10-17 importCount = getReaderContext().getReader().loadBeanDefinitions( StringUtils.applyRelativePath(baseLocation, location), actualResources); } if (logger.isTraceEnabled()) { logger.trace('Imported ' + importCount + ' bean definitions from relative location [' + location + ']'); } } }}

我們來(lái)解析下這段代碼是怎么一個(gè)流程:

1.首先通過(guò)resource標(biāo)簽解析到它的屬性值,并且判讀字符串值是否為空。

2.接下來(lái)它還會(huì)通過(guò)當(dāng)前上下文環(huán)境去解析字符串路徑里面的占位符,這點(diǎn)我們?cè)谥拔恼轮蟹治鲞^(guò)。

2.接下來(lái)判斷是否是絕對(duì)路徑,通過(guò)調(diào)用ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();來(lái)判斷,劃重點(diǎn):以 classpath*: 或者 classpath: 開頭為絕對(duì)路徑,或者可以生成一個(gè)URI實(shí)例就是當(dāng)作絕對(duì)路徑,或者也可以URI的isAbsolute來(lái)判斷

3.如果是絕對(duì)路徑那么我們通過(guò)getReaderContext().getReader()獲取到XmlBeanDefinitionReader然后調(diào)用它的loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources)函數(shù)

4.如果不是絕對(duì)路徑那么我們嘗試生成相對(duì)當(dāng)前資源的路徑(這點(diǎn)很重要),再通過(guò)loadBeanDefinitions方法來(lái)加載這個(gè)配置文件中的BeanDefinitions。這里有個(gè)細(xì)節(jié)需要我們注意,就是它為什么要嘗試去判斷資源是否存在?就是如果存在的話那么直接調(diào)用loadBeanDefinitions(Resource resource)方法,也就是說(shuō)這里肯定是加載單個(gè)資源文件,如方法注釋所說(shuō):

/** * Load bean definitions from the specified XML file. * @param resource the resource descriptor for the XML file * @return the number of bean definitions found * @throws BeanDefinitionStoreException in case of loading or parsing errors */@Overridepublic int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException { //load中去注冊(cè)BeanDefinition return loadBeanDefinitions(new EncodedResource(resource));}

從指定的xml文件加載Bean定義。如果不存在,那么就跟絕對(duì)路徑一樣會(huì)調(diào)用loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources)函數(shù),我們來(lái)看看這個(gè)函數(shù)的定義:

/** * Load bean definitions from the specified resource location. * <p>The location can also be a location pattern, provided that the * ResourceLoader of this bean definition reader is a ResourcePatternResolver. * @param location the resource location, to be loaded with the ResourceLoader * (or ResourcePatternResolver) of this bean definition reader * @param actualResources a Set to be filled with the actual Resource objects * that have been resolved during the loading process(要填充加載過(guò)程中已解析的實(shí)際資源對(duì)象*的集合). May be {@code null} * to indicate that the caller is not interested in those Resource objects. */public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {

解釋很清楚,這個(gè)location是指從指定資源路徑加載BeanDefinitions。

總結(jié)

從源碼可以看出從外部導(dǎo)入配置文件也就是給了通過(guò)一個(gè)總的配置文件來(lái)加載各個(gè)單一配置文件擴(kuò)展的機(jī)會(huì)。

以上就是Spring通過(guò)<import>標(biāo)簽導(dǎo)入外部配置文件的詳細(xì)內(nèi)容,更多關(guān)于Spring 導(dǎo)入外部配置文件的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Spring
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
狠狠久久伊人| 日韩精品免费视频一区二区三区 | 日韩一区三区| 日韩va亚洲va欧美va久久| 免费视频亚洲| 亚洲高清成人| 精品成人免费一区二区在线播放| 精品国产aⅴ| 久久午夜影院| 久久精品99久久久| 亚洲色图网站| 日韩精品久久久久久久软件91| 日韩一级欧洲| 国产视频久久| 一区二区三区网站| 日韩精品第一| 不卡一二三区| 亚洲天堂久久| 中文字幕一区久| 久久久久午夜电影| 999精品色在线播放| 在线观看免费一区二区| 99热精品在线| 日韩国产一区二| 国产精品久久久网站| 国产精品一区二区免费福利视频| 91麻豆精品激情在线观看最新| 国产精品视频一区二区三区综合 | 国产不卡一区| 91精品久久久久久久久久不卡| 亚洲精品123区| 亚洲三级国产| 日本成人在线视频网站| 18国产精品| 久久精品官网| 日本一区福利在线| 精品久久97| 亚洲我射av| 成人国产精品| 日本va欧美va精品| jiujiure精品视频播放| 久久精品国产99国产| 免费在线看一区| 久久精品二区三区| 欧美日本精品| 亚洲成人三区| 国产精品久久久久久久久久久久久久久 | 精品久久久中文字幕| 日韩视频网站在线观看| 亚洲一级少妇| 亚洲精品在线国产| 亚洲精品国产嫩草在线观看| 日精品一区二区三区| 精品久久不卡| 五月天综合网站| 老鸭窝一区二区久久精品| 久久亚洲国产| 国产福利资源一区| 99久久婷婷这里只有精品| 中文字幕日本一区二区| 日韩.com| 视频一区日韩精品| 国产成人精品三级高清久久91 | 九色精品91| 国产精品久久乐| 一本一道久久a久久| 久久夜夜操妹子| 国产乱码精品一区二区三区四区| 亚洲免费激情| 久久精品系列| 日本午夜精品久久久| 三级亚洲高清视频| 亚洲欧美一区在线| 国产综合色区在线观看| 国产精东传媒成人av电影| 亚洲精品2区| 秋霞影视一区二区三区| 国产精品对白| 国产精品久久久久久久久久齐齐| 亚洲精品日韩久久| 国产精品成久久久久| 久久久免费人体| 国产精品亚洲片在线播放| 国产图片一区| 国产调教一区二区三区| 国产一二在线播放| 精品不卡一区| 中文亚洲免费| 欧美成人高清| 神马午夜久久| 国产伊人久久| 亚洲性色av| 黄色亚洲在线| 美女被久久久| 欧美日韩国产在线观看网站 | 欧美日韩91| 老色鬼精品视频在线观看播放| 麻豆精品视频在线观看免费| 欧美日韩1区| 日韩影院二区| 欧美日韩在线网站| 精品少妇av| 蜜桃tv一区二区三区| 蜜桃视频一区二区三区| 美女免费视频一区| 免费在线观看日韩欧美| 精品欧美日韩精品| 日本欧美久久久久免费播放网| 久久精品99国产精品| 亚洲精品一区二区在线播放∴| 久久久免费人体| 久久国产精品久久久久久电车| 美女久久99| 免费一级片91| se01亚洲视频 | 亚洲精品2区| 亚洲青青久久| av免费不卡国产观看| 一区二区三区四区在线看| 亚洲三级视频| 欧美日韩免费看片| 国产欧美日韩一区二区三区四区| 国内精品99| 国产伊人精品| 色婷婷精品视频| 国产va免费精品观看精品视频| 91精品国产自产在线丝袜啪| 婷婷激情综合| 日韩欧美一区二区三区在线视频| 国产调教精品| 国产毛片久久久| 欧美日韩亚洲三区| 爽爽淫人综合网网站| 99视频+国产日韩欧美| 久久裸体视频| 日韩不卡免费高清视频| 国精品一区二区| 午夜a一级毛片亚洲欧洲| 91久久亚洲| 亚洲精品欧洲| 妖精视频成人观看www| 久久精品国产大片免费观看| 日韩欧美午夜| 日韩不卡视频在线观看| 中文久久精品| 日本色综合中文字幕| 日本不卡视频在线| 视频一区中文字幕精品| 日韩和欧美一区二区三区| 亚洲精品亚洲人成在线观看| 婷婷综合一区| 国产成人精品一区二区三区视频| 成人精品久久| 97精品97| 视频一区免费在线观看| 欧美日韩亚洲一区| 久久中文亚洲字幕| 欧美一级二级三级视频| 国产高清不卡| 欧美成人久久| 999国产精品999久久久久久| 日本精品国产| 国产精品一区亚洲| 欧美不卡高清| 亚洲欧美日韩国产综合精品二区| 视频一区二区三区在线| 91亚洲无吗| 久久精品青草| 欧美日韩国产一区精品一区| 亚洲免费观看| 国产成人精品三级高清久久91| 黄色精品网站| а√天堂8资源中文在线| 影音国产精品| 国产a亚洲精品| 日韩一区二区三区免费视频| 天堂√中文最新版在线| 日本国产欧美| 99久久久久国产精品| 国产精品视频一区二区三区| 国产亚洲一级| 激情亚洲影院在线观看| 欧美国产另类| 国产亚洲亚洲| 国产精品av久久久久久麻豆网| 国产福利一区二区精品秒拍 | 亚洲一级大片| 亚洲成人一区在线观看| 欧美极品一区二区三区| 视频在线观看一区| 欧美高清一区| 久久精品123| 精品日韩视频| 日韩不卡一区二区三区| 欧美日韩va| 色综合视频一区二区三区日韩| 日韩欧美2区| 成人影视亚洲图片在线| 国产精品久久久久9999高清| 日韩av中文在线观看|