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
}
}
代码2为当遇到解析节点为<alias>
标签,则根据给定的name和alias进行关联。下面我们看看<alias>
在配置文件中的用法:
我们继续回到源代码,看看spring如何实现别名的配置:
protected void processAliasRegistration(Element ele) {
//获取name属性的值
String name = ele.getAttribute(NAME_ATTRIBUTE);
//获取alias属性的值
String alias = ele.getAttribute(ALIAS_ATTRIBUTE);
boolean valid = true;
//name的非空验证
if (!StringUtils.hasText(name)) {
getReaderContext().error("Name must not be empty", ele);
valid = false;
}
//alias的非空验证
if (!StringUtils.hasText(alias)) {
getReaderContext().error("Alias must not be empty", ele);
valid = false;
}
//通过非空验证后
if (valid) {
try {
//注册别名
getReaderContext().getRegistry().registerAlias(name, alias);
}
catch (Exception ex) {
...
}
//注册完别名的通知
getReaderContext().fireAliasRegistered(name, alias, extractSource(ele));
}
}
SimpleAliasRegistry:
public void registerAlias(String name, String alias) {
Assert.hasText(name, "'name' must not be empty");
Assert.hasText(alias, "'alias' must not be empty");
//假如name与alias相同,则会将别名移除。因为此时不需要别名,直接使用name即可,并把已注册进来的别名去除
if (alias.equals(name)) {
this.aliasMap.remove(alias);
}
else {
//假如name与alias不相同,获取已注册的别名
String registeredName = this.aliasMap.get(alias);
if (registeredName != null) {
if (registeredName.equals(name)) {
//一个存在的别名,则不需要重新注册
return;
}
if (!allowAliasOverriding()) {
...
}
}
//检查注册进来的别名是否已存在,存在则报错,防止循环注册
checkForAliasCircle(name, alias);
//注册别名
this.aliasMap.put(alias, name);
}
}