参考: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));
}