这是
SimpleAliasRegistry 实现注册别名,进入一个检查方法 this.checkForAliasCircle(name, alias);
比较是否注册别名alias.equals(this.canonicalName(name))
public void registerAlias(String name, String alias) {
Assert.hasText(name, "'name' must not be empty");
Assert.hasText(alias, "'alias' must not be empty");
if (alias.equals(name)) {
this.aliasMap.remove(alias);
} else {
if (!this.allowAliasOverriding()) {
String registeredName = (String)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 + "'.");
}
}
this.checkForAliasCircle(name, alias);
this.aliasMap.put(alias, name);
}
}
protected void checkForAliasCircle(String name, String alias) {
if (alias.equals(this.canonicalName(name))) {
throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" + name + "': Circular reference - '" + name + "' is a direct or indirect alias for '" + alias + "' already");
}
}
public String canonicalName(String name) {
String canonicalName = name;
String resolvedName;
do {
resolvedName = (String)this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
} while(resolvedName != null);
return canonicalName;
}
首先进入代码给flag变量赋值 resolvedName= null,然后进入循环,获取结果
有一点要说的是 canonicalName = resolvedName; 这段代码,如果数据,不存在,null!=null,直接跳出去,
如果有外部的线程进来,那么
但是数据存在,这一线段,重新赋值课查找key,一般不存在,如果存在,再次查找,知道null位置,但是有没有对外部代码的影响,一般不会,除非存在链式map
如图所示
{alias_8=alias_9, alias_7=alias_8, alias_9=alias_10, alias_4=alias_5, alias_3=alias_4, alias_6=alias_7, alias_5=alias_6, alias_0=alias_1, alias_2=alias_3, alias_1=alias_2}
前面的value,作为后面的key,这样,才会对外部有影响
一下纯属自己的猜想
再使用spring 容器的时候,一般使用类名作为alisa和name,当存在不同包有相同的时候,应该会加完整的包路径,
或者,一开始就是完整的类资源路径,这个在配置文件解析或者扫描的时候也支持的,这样就完全解决这样的问题