电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

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

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

瀏覽:3日期: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
相關文章:
主站蜘蛛池模板: 全自动面膜机_面膜折叠机价格_面膜灌装机定制_高速折棉机厂家-深圳市益豪科技有限公司 | 起好名字_取个好名字_好名网免费取好名在线打分 | 定做大型恒温循环水浴槽-工业用不锈钢恒温水箱-大容量低温恒温水槽-常州精达仪器 | 运动木地板厂家,篮球场木地板品牌,体育场馆木地板安装 - 欧氏运动地板 | 水轮机密封网 | 水轮机密封产品研发生产厂家 | 密集架|电动密集架|移动密集架|黑龙江档案密集架-大量现货厂家销售 | 首页|专注深圳注册公司,代理记账报税,注册商标代理,工商变更,企业400电话等企业一站式服务-慧用心 | 回收二手冲床_金丰旧冲床回收_协易冲床回收 - 大鑫机械设备 | 碎石机设备-欧版反击破-欧版颚式破碎机(站)厂家_山东奥凯诺机械 高低温试验箱-模拟高低温试验箱订制-北京普桑达仪器科技有限公司【官网】 | 交变/复合盐雾试验箱-高低温冲击试验箱_安奈设备产品供应杭州/江苏南京/安徽马鞍山合肥等全国各地 | 全自动贴标机-套标机-工业热风机-不干胶贴标机-上海厚冉机械 | 工业rfid读写器_RFID工业读写器_工业rfid设备厂商-ANDEAWELL | 防爆电机_防爆电机型号_河南省南洋防爆电机有限公司 | CE认证_FCC认证_CCC认证_MFI认证_UN38.3认证-微测检测 CNAS实验室 | 升降机-高空作业车租赁-蜘蛛车-曲臂式伸缩臂剪叉式液压升降平台-脚手架-【普雷斯特公司厂家】 | 自动螺旋上料机厂家价格-斗式提升机定制-螺杆绞龙输送机-杰凯上料机 | 深圳市东信高科自动化设备有限公司| 天津试验仪器-电液伺服万能材料试验机,恒温恒湿标准养护箱,水泥恒应力压力试验机-天津鑫高伟业科技有限公司 | 重庆轻质隔墙板-重庆安吉升科技有限公司 | 葡萄酒灌装机-食用油灌装机-液体肥灌装设备厂家_青州惠联灌装机械 | b2b网站大全,b2b网站排名,找b2b网站就上地球网 | 汽车整车综合环境舱_军标砂尘_盐雾试验室试验箱-无锡苏南试验设备有限公司 | 磨煤机配件-高铬辊套-高铬衬板-立磨辊套-盐山县宏润电力设备有限公司 | 车间除尘设备,VOCs废气处理,工业涂装流水线,伸缩式喷漆房,自动喷砂房,沸石转轮浓缩吸附,机器人喷粉线-山东创杰智慧 | 权威废金属|废塑料|废纸|废铜|废钢价格|再生资源回收行情报价中心-中废网 | 吸音板,隔音板,吸音材料,吸音板价格,声学材料 - 佛山诺声吸音板厂家 | 右手官网|右手工业设计|外观设计公司|工业设计公司|产品创新设计|医疗产品结构设计|EMC产品结构设计 | 郑州爱婴幼师学校_专业幼师培训_托育师培训_幼儿教育培训学校 | 挖掘机挖斗和铲斗生产厂家选择徐州崛起机械制造有限公司 | 橡胶弹簧|复合弹簧|橡胶球|振动筛配件-新乡市永鑫橡胶厂 | 新能源汽车电机定转子合装机 - 电机维修设备 - 睿望达 | 高温热泵烘干机,高温烘干热泵,热水设备机组_正旭热泵 | 垃圾清运公司_环卫保洁公司_市政道路保洁公司-华富环境 | 胶辊硫化罐_胶鞋硫化罐_硫化罐厂家-山东鑫泰鑫智能装备有限公司 意大利Frascold/富士豪压缩机_富士豪半封闭压缩机_富士豪活塞压缩机_富士豪螺杆压缩机 | 精雕机-火花机-精雕机 cnc-高速精雕机-电火花机-广东鼎拓机械科技有限公司 | 【中联邦】增稠剂_增稠粉_水性增稠剂_涂料增稠剂_工业增稠剂生产厂家 | 江西自考网-江西自学考试网 | 蜗轮丝杆升降机-螺旋升降机-丝杠升降机厂家-润驰传动 | 陕西视频监控,智能安防监控,安防系统-西安鑫安5A安防工程公司 | 南京技嘉环保科技有限公司-杀菌除臭剂|污水|垃圾|厕所|橡胶厂|化工厂|铸造厂除臭剂 | 广州番禺搬家公司_天河黄埔搬家公司_企业工厂搬迁_日式搬家_广州搬家公司_厚道搬迁搬家公司 |