在对bean进行定义的时候,除了使用id属性来指定名称之外,为了提供多个名称,可以使用alias标签来指定。
在定义bean的时候就指定所有的别名并不总是恰当的。有时候我们可能在当前位置为别处定义的bean引入别名。在XML配置文件中,可以单独使用
同样,Spring还有另外一种声明别名的方式
举个例子;如果组件A在XML配置文件中定义了一个名字为componentA的DataSource类型的bean,但是组件B却想在其XML文件中componentB命名来引用这个bean。而在主程序MyApp的XML配置文件中想用myApp的名字来引用。在这个情形下我们就可以用alias元素来实现
这样一来,每个组件以及主程序都可以通过唯一的名字来引用同一个数据源。
protected void processAliasRegistration(Element ele) {
//todo.获取beanName
String name = ele-getAttribute(NAME_ATTRIBUTE);
//todo.获aLias
String alias = ele-getAttribute(ALIAS_ATTRIBUTE);boolean valid. = true;
if (!Stringutils.hasText(name)) {
getReaderContext().error( message: "Name must. not be. empty", ele);
valid=. false;
}
if (!Stringutils.hasText(alias)).{
getReaderContext().error( message: "Alias must. not be. empty", ele);valid.=. false;
}
if (valid){
try{
//todo.注册aLias
getReaderContext().getRegistry().registerAlias(name, alias);
}
catch (Exception ex). {
getReaderContext().error( message: "Failed to register alias.'".+.alias +
"'for bean with name. '"+ name+. "'", ele, ex);
//todo注册别之后通知监所器 相应的处理
getReaderContext().fireAliasRegistered(name, alias, extractSource(ele));
}
}
可以看出bean和alias解析大同小异,都是将别名与beanName组成一队注册到register中。
AliasRegistry.java(接口)--->SimpleAliasRegistry.java(实现)
/** Map from alias to canonical name */
private final Map aliasMap = new ConcurrentHashMap(16);
public void registerAlias(String name, String alias) {
Assert.hasText(name, "'name' must not be empty");
Assert.hasText(alias, "'alias' must not be empty");
//todo 如果beanName与alias相同的话不记录alias,并删除对应的alias
if (alias.equals(name)) {
this.aliasMap.remove(alias);
}
else {
//todo 如果alias不允许被覆盖则抛出异常
if (!allowAliasOverriding()) {
String registeredName = this.aliasMap.get(alias);
if (registeredName != null && !registeredName.equals(name)) {
throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" +
name + "': It is already registered for name '" + registeredName + "'.");
}
}
//todo 当A->B存在时,若再次出现A->B->C时候则会抛出异常
checkForAliasCircle(name, alias);
this.aliasMap.put(alias, name);
}
}