Spring IoC的细节--DefaultBeanDefinitionDocumentReader.importBeanDefinitionResource(Element ele)

参考:https://www.cnblogs.com/honger/p/6815181.html

<import>标签例子:
在这里插入图片描述

DefaultBeanDefinitionDocumentReader:

    //使用Spring的Bean规则解析Document元素节点
	private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		//如果元素节点是<Import>导入元素,进行导入解析
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
			importBeanDefinitionResource(ele);  //代码1
		}
		//如果元素节点是<Alias>别名元素,进行别名解析
		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
			processAliasRegistration(ele);    //代码2
		}
		//元素节点既不是导入元素,也不是别名元素,即普通的<Bean>元素,按照Spring的Bean规则解析元素
		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
			//主线
			processBeanDefinition(ele, delegate);   //代码3
		}
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			// recurse
			doRegisterBeanDefinitions(ele);   //代码4
		}
	}

代码1讲述了,当遇到<import>属性后,spring会优先将该标签对应的配置文件的Bean加载并注册进IoC容器:

    //解析<Import>导入元素,从给定的导入路径加载Bean定义资源到Spring IOC  容器中
	protected void importBeanDefinitionResource(Element ele) {
		// 获取给定的导入元素的location属性
		String location = ele.getAttribute(RESOURCE_ATTRIBUTE);

		//验证非空
		if (!StringUtils.hasText(location)) {
			getReaderContext().error("Resource location must not be empty", ele);
			return;
		}

		//处理配置
		location = getReaderContext().getEnvironment().resolveRequiredPlaceholders(location);

		Set<Resource> actualResources = new LinkedHashSet<>(4);

		boolean absoluteLocation = false;
		try {
			//判断location的值为绝对路径还是相对路径,前缀为“classpath*:”、“classpath:”开头为绝对路径
			absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();  
		}
		catch (URISyntaxException ex) {
			...
		}

		//绝对路径,则直接进行加载,回调到AbstractBeanDefinitionReader的loadBeanDefinitions方法
		if (absoluteLocation) {
			try {
				int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources);
				...
			}
			catch (BeanDefinitionStoreException ex) {
				...
			}
		}
		else {
			//假如为相对路径
			try {
				int importCount;
				//将路径配置转为资源
				Resource relativeResource = getReaderContext().getResource().createRelative(location);
				//假如可以获取到资源,则回调到AbstractBeanDefinitionReader的loadBeanDefinitions方法进行加载
				if (relativeResource.exists()) {
					importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource);
					actualResources.add(relativeResource);
				}
				else {
					//获取不到资源,则加上基础路径,再进行加载操作
					String baseLocation = getReaderContext().getResource().getURL().toString();
					importCount = getReaderContext().getReader().loadBeanDefinitions(
							StringUtils.applyRelativePath(baseLocation, location), actualResources);
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]");
				}
			}
			catch (IOException ex) {
				...
			}
			
		}
		Resource[] actResArray = actualResources.toArray(new Resource[actualResources.size()]);
		//发送容器导入资源处理完成事件通知
		getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele));
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值