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

您的位置:首頁技術文章
文章詳情頁

Spring通過<import>標簽導入外部配置文件

瀏覽:30日期:2023-07-07 15:17:21
目錄示例原理DefaultBeanDefinitionDocumentReaderparseDefaultElementimportBeanDefinitionResource總結示例

我們先來看下配置文件是怎么導入外部配置文件的?先定義一個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>

我們看到里面定義了一個標簽并用屬性resource聲明了導入的資源文件為spring-config.xml。我們再來看下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='中國'/> <property name='gender' value='女'/> </bean></beans>

然后我們可以實例化一個BeanFactory來加載spring-import這個配置文件了。

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

如果沒問題的話,我們可以獲取到outerPerson這個bean并打印了。

Person [0, john wonder]原理

我們來通過源碼分析下Spring是如何解析import標簽并加載這個導入的配置文件的。首先我們到DefaultBeanDefinitionDocumentReader類中看下:

DefaultBeanDefinitionDocumentReader

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

public static final String IMPORT_ELEMENT = 'import';

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

parseDefaultElement

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

這里就是我們要找的導入外部配置文件加載Bean定義的源代碼,我們再重點看下importBeanDefinitionResource函數:

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}' // // 解析系統屬性,格式如 :'${user.dir}' location = getReaderContext().getEnvironment().resolveRequiredPlaceholders(location); Set<Resource> actualResources = new LinkedHashSet<>(4); // Discover whether the location is an absolute or relative URI //// 判斷 location 是相對路徑還是絕對路徑 boolean absoluteLocation = false; try { //以 classpath*: 或者 classpath: 開頭為絕對路徑 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? //絕對路徑 也會調用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 { //如果是相對路徑,則先計算出絕對路徑得到 Resource,然后進行解析 // No URL -> considering resource location as relative to the current file. try { int importCount; Resource relativeResource = getReaderContext().getResource().createRelative(location); //如果相對路徑 這個資源存在 那么就加載這個bean 定義 if (relativeResource.exists()) { importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource); actualResources.add(relativeResource); } else { String baseLocation = getReaderContext().getResource().getURL().toString(); //todo import節點 內部會調用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 + ']'); } } }}

我們來解析下這段代碼是怎么一個流程:

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

2.接下來它還會通過當前上下文環境去解析字符串路徑里面的占位符,這點我們在之前文章中分析過。

2.接下來判斷是否是絕對路徑,通過調用ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();來判斷,劃重點:以 classpath*: 或者 classpath: 開頭為絕對路徑,或者可以生成一個URI實例就是當作絕對路徑,或者也可以URI的isAbsolute來判斷

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

4.如果不是絕對路徑那么我們嘗試生成相對當前資源的路徑(這點很重要),再通過loadBeanDefinitions方法來加載這個配置文件中的BeanDefinitions。這里有個細節需要我們注意,就是它為什么要嘗試去判斷資源是否存在?就是如果存在的話那么直接調用loadBeanDefinitions(Resource resource)方法,也就是說這里肯定是加載單個資源文件,如方法注釋所說:

/** * 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中去注冊BeanDefinition return loadBeanDefinitions(new EncodedResource(resource));}

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

/** * 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(要填充加載過程中已解析的實際資源對象*的集合). 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 {

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

總結

從源碼可以看出從外部導入配置文件也就是給了通過一個總的配置文件來加載各個單一配置文件擴展的機會。

以上就是Spring通過<import>標簽導入外部配置文件的詳細內容,更多關于Spring 導入外部配置文件的資料請關注好吧啦網其它相關文章!

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚久久调教视频| 超碰超碰人人人人精品| 久久国产精品色av免费看| 石原莉奈在线亚洲二区| 99国产一区| 国产精品外国| 亚洲欧美日韩视频二区| 乱人伦精品视频在线观看| 久久国产精品久久w女人spa| 久久香蕉精品| 亚洲日本免费电影| 青青草国产精品亚洲专区无| 在线精品观看| 亚洲日本国产| 欧美日韩一区二区三区在线电影| 国产午夜一区| 精品国产午夜| av一区在线| 午夜欧美视频| 亚洲欧洲专区| 国产精品地址| 欧美国产小视频| 亚洲高清二区| 国产精品免费看| 国产一区二区精品久| 日韩激情一区二区| 日韩在线网址| 国产精品久久久久av蜜臀 | 久久精品成人| 日韩视频一区| 久久国产免费看| 成人在线免费观看网站| 日韩精品免费一区二区三区| 日韩视频中文| 欧美亚洲二区| 免费污视频在线一区| 男女男精品网站| 三上悠亚国产精品一区二区三区 | 国产精品亲子伦av一区二区三区| 精品99久久| 亚洲成人一区| 欧美一区精品| 99国产精品一区二区| 国产亚洲亚洲| 亚洲大片在线| 亚洲免费毛片| 国产精品nxnn| 91精品亚洲| 日韩激情网站| 四虎4545www国产精品 | 欧美成人国产| 日韩国产在线观看| 在线中文字幕播放| 亚洲制服欧美另类| 麻豆视频在线看| 日韩精品视频中文字幕| 日本免费久久| 日韩久久一区| 亚洲一本视频| 国产一区三区在线播放| 亚洲午夜av| 久久久久亚洲精品中文字幕| 午夜一级久久| 国产精品巨作av| 欧美久久香蕉| 欧美日本精品| 色天使综合视频| 国产精品对白| 精品久久电影| 国产人成精品一区二区三| 不卡在线一区| 精品视频久久| 日韩成人在线看| 午夜久久tv| 中文字幕在线视频久| 亚洲尤物在线| 亚洲精品国产嫩草在线观看 | 红桃视频国产一区| 国产一区二区三区日韩精品 | 免费一级片91| 红桃视频国产精品| 日韩欧美午夜| 欧美精品第一区| 久久精品 人人爱| 欧美日韩国产传媒| 成人国产精品久久| 国产精品igao视频网网址不卡日韩| 午夜日本精品| 久久亚洲国产| 青青青免费在线视频| 国产精品资源| 久久精品99久久久| 日韩区一区二| 亚洲人成高清| 一区二区三区午夜视频| 午夜在线精品偷拍| 亚洲精品成人| 五月精品视频| 日韩欧美一区二区三区在线观看| 欧美在线不卡| 亚洲精品乱码日韩| 麻豆91精品| 玖玖玖国产精品| 日韩一级不卡| 性色一区二区| 中文字幕一区二区三区在线视频| 红桃视频欧美| 国产色综合网| 99国产精品视频免费观看一公开| 婷婷亚洲综合| 伊人影院久久| 欧美在线网站| 亚洲综合日本| 久久国产高清| 免费日韩视频| 日韩中文欧美在线| 男人的天堂久久精品| 亚洲伊人影院| 日韩高清不卡一区| 欧美精品国产| 美女久久99| 欧美xxxx中国| 久久精品国产99久久| 99热精品在线| 日韩在线观看一区二区三区| 中文一区一区三区免费在线观 | 日韩精品国产精品| 国产suv精品一区二区四区视频 | 日本精品影院| 一区二区日韩免费看| 国产精品美女午夜爽爽| 韩国久久久久久| 免费看精品久久片| 卡一卡二国产精品| 免播放器亚洲一区| 久久久免费人体| 亚洲福利久久| 91欧美精品| 亚洲电影有码| 欧美欧美黄在线二区| 夜鲁夜鲁夜鲁视频在线播放| 免费国产自线拍一欧美视频| 欧美一区二区三区久久| 欧美经典一区| 欧美日韩精品在线一区| 日韩激情一区| 午夜精品网站| 热久久免费视频| 日韩精品dvd| 日韩**一区毛片| 精品久久视频| 激情欧美一区| 男女男精品视频网| 国产精品久久久久久久免费观看 | 樱桃视频成人在线观看| 神马日本精品| 久久高清国产| 日韩国产在线观看| 蜜臀久久99精品久久久久宅男| 欧美影院三区| 国产精品尤物| 午夜av不卡| 亚洲一卡久久| 国产人成精品一区二区三| 麻豆精品av| 中文字幕一区二区三区在线视频| 日韩av在线免费观看不卡| 精品国产亚洲一区二区在线观看| 日韩欧美一区二区三区在线观看| 国产精品日本| 日韩高清中文字幕一区二区| 蜜桃av一区二区| 老色鬼精品视频在线观看播放| 日韩精品久久久久久久电影99爱| 欧美日韩日本国产亚洲在线| 精品成av人一区二区三区| 99精品视频在线观看免费播放| 蜜桃久久精品一区二区| 麻豆精品少妇| 宅男噜噜噜66国产日韩在线观看| 国产91欧美| 亚洲精选久久| av免费不卡国产观看| 日韩在线一区二区| 久久不卡日韩美女| 成人污污视频| 久久不见久久见中文字幕免费| 欧美日韩亚洲在线观看| 日韩毛片网站| 国产黄大片在线观看| 欧美日韩一区二区三区四区在线观看 | 日韩伦理一区| 日本亚洲不卡| 久久精品一区二区国产| 欧美.日韩.国产.一区.二区 | 亚洲福利国产| 美腿丝袜亚洲一区| 亚洲高清激情| 久久av偷拍| 性欧美videohd高精|