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

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

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

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

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

我們看到里面定義了一個標(biāo)簽并用屬性resource聲明了導(dǎo)入的資源文件為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標(biāo)簽并加載這個導(dǎo)入的配置文件的。首先我們到DefaultBeanDefinitionDocumentReader類中看下:

DefaultBeanDefinitionDocumentReader

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

public static final String IMPORT_ELEMENT = 'import';

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

parseDefaultElement

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

這里就是我們要找的導(dǎo)入外部配置文件加載Bean定義的源代碼,我們再重點看下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 是相對路徑還是絕對路徑 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? //絕對路徑 也會調(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 { //如果是相對路徑,則先計算出絕對路徑得到 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節(jié)點 內(nèi)部會調(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 + ']'); } } }}

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

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

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

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

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

4.如果不是絕對路徑那么我們嘗試生成相對當(dāng)前資源的路徑(這點很重要),再通過loadBeanDefinitions方法來加載這個配置文件中的BeanDefinitions。這里有個細節(jié)需要我們注意,就是它為什么要嘗試去判斷資源是否存在?就是如果存在的話那么直接調(diào)用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定義。如果不存在,那么就跟絕對路徑一樣會調(diào)用loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources)函數(shù),我們來看看這個函數(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(要填充加載過程中已解析的實際資源對象*的集合). 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。

總結(jié)

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

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

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 钛板_钛管_钛棒_钛盘管-无锡市盛钛科技有限公司 | 船用烟火信号弹-CCS防汛救生圈-船用救生抛绳器(海威救生设备) | 企小优-企业数字化转型服务商_网络推广_网络推广公司 | 北京律师事务所_房屋拆迁律师_24小时免费法律咨询_云合专业律师网 | 自进式锚杆-自钻式中空注浆锚杆-洛阳恒诺锚固锚杆生产厂家 | 对夹式止回阀_对夹式蝶形止回阀_对夹式软密封止回阀_超薄型止回阀_不锈钢底阀-温州上炬阀门科技有限公司 | 洗砂机械-球磨制砂机-洗沙制砂机械设备_青州冠诚重工机械有限公司 | 电磁铁_小型推拉电磁铁_电磁阀厂家-深圳市宗泰电机有限公司 | 上海地磅秤|电子地上衡|防爆地磅_上海地磅秤厂家–越衡称重 | 地脚螺栓_材质_标准-永年县德联地脚螺栓厂家 | FAG轴承,苏州FAG轴承,德国FAG轴承-恩梯必传动设备(苏州)有限公司 | 安平县鑫川金属丝网制品有限公司,防风抑尘网,单峰防风抑尘,不锈钢防风抑尘网,铝板防风抑尘网,镀铝锌防风抑尘网 | 电磁辐射仪-电磁辐射检测仪-pm2.5检测仪-多功能射线检测仪-上海何亦仪器仪表有限公司 | 恒温恒湿试验箱厂家-高低温试验箱维修价格_东莞环仪仪器_东莞环仪仪器 | 上海小程序开发-上海小程序制作公司-上海网站建设-公众号开发运营-软件外包公司-咏熠科技 | 跨境物流_美国卡派_中大件运输_尾程派送_海外仓一件代发 - 广州环至美供应链平台 | 悬浮拼装地板_篮球场木地板翻新_运动木地板价格-上海越禾运动地板厂家 | 碎石机设备-欧版反击破-欧版颚式破碎机(站)厂家_山东奥凯诺机械 高低温试验箱-模拟高低温试验箱订制-北京普桑达仪器科技有限公司【官网】 | 寮步纸箱厂_东莞纸箱厂 _东莞纸箱加工厂-东莞市寮步恒辉纸制品厂 | 水冷散热器_水冷电子散热器_大功率散热器_水冷板散热器厂家-河源市恒光辉散热器有限公司 | 老房子翻新装修,旧房墙面翻新,房屋防水补漏,厨房卫生间改造,室内装潢装修公司 - 一修房屋快修官网 | 旗杆生产厂家_不锈钢锥形旗杆价格_铝合金电动旗杆-上海锥升金属科技有限公司 | 齿辊分级破碎机,高低压压球机,立式双动力磨粉机-郑州长城冶金设备有限公司 | crm客户关系管理系统,销售管理系统,crm系统,在线crm,移动crm系统 - 爱客crm | 手板-手板模型-手板厂-手板加工-生产厂家,[东莞创域模型] | 衬塑设备,衬四氟设备,衬氟设备-淄博鲲鹏防腐设备有限公司 | 贵州成人高考网_贵州成考网| 塑钢课桌椅、学生课桌椅、课桌椅厂家-学仕教育设备首页 | PC阳光板-PC耐力板-阳光板雨棚-耐力板雨棚,厂家定制[优尼科板材] | ★店家乐|服装销售管理软件|服装店收银系统|内衣店鞋店进销存软件|连锁店管理软件|收银软件手机版|会员管理系统-手机版,云版,App | 【ph计】|在线ph计|工业ph计|ph计厂家|ph计价格|酸度计生产厂家_武汉吉尔德科技有限公司 | 匀胶机旋涂仪-声扫显微镜-工业水浸超声-安赛斯(北京)科技有限公司 | 烽火安全网_加密软件、神盾软件官网 | 视觉检测设备_自动化检测设备_CCD视觉检测机_外观缺陷检测-瑞智光电 | Type-c防水母座|贴片母座|耳机接口|Type-c插座-深圳市步步精科技有限公司 | 液压压力机,液压折弯机,液压剪板机,模锻液压机-鲁南新力机床有限公司 | 众能联合-提供高空车_升降机_吊车_挖机等一站工程设备租赁 | 气动隔膜阀_气动隔膜阀厂家_卫生级隔膜阀价格_浙江浙控阀门有限公司 | 生物制药洁净车间-GMP车间净化工程-食品净化厂房-杭州波涛净化设备工程有限公司 | 好看的韩国漫画_韩漫在线免费阅读-汗汗漫画 | 济南ISO9000认证咨询代理公司,ISO9001认证,CMA实验室认证,ISO/TS16949认证,服务体系认证,资产管理体系认证,SC食品生产许可证- 济南创远企业管理咨询有限公司 郑州电线电缆厂家-防火|低压|低烟无卤电缆-河南明星电缆 |