/**别名处理流程**/
org.springframework.core.SimpleAliasRegistry#registerAlias
/** Map from alias to canonical name */
别名到实例名的映射
privatefinal Map<String, String> aliasMap =newConcurrentHashMap<>(16);@OverridepublicvoidregisterAlias(String name, String alias){
同步锁 为了防止并发问题导致数据出现别名循环引用
//此处注意:很多人疑问的地方,用了ConcurrentHashMap,为何此处还要加锁呢?有必要吗?//答:非常有必要的。因为ConcurrentHashMap只能保证单个put、remove方法的原子性。而不能保证多个操作同时的原子性。比如我一边添加、一边删除 显然这是不被允许的synchronized(this.aliasMap){if(alias.equals(name)){
别名与实例名相同,不需要放在别名Map中,移除别名与实例名的映射
this.aliasMap.remove(alias);}else{
String registeredName =this.aliasMap.get(alias);if(registeredName != null){
如果已经存在,直接返回
if(registeredName.equals(name)){// An existing alias - no need to re-registerreturn;}
是否允许别名重写,默认trueif(!allowAliasOverriding()){thrownewIllegalStateException("Cannot define alias '"+ alias +"' for name '"+
name +"': It is already registered for name '"+ registeredName +"'.");}}
检查别名循环引用问题 不允许别名循环依赖
checkForAliasCircle(name, alias);
存入别名
this.aliasMap.put(alias, name);}}}protectedvoidcheckForAliasCircle(String name, String alias){if(hasAlias(alias, name)){thrownewIllegalStateException("Cannot register alias '"+ alias +"' for name '"+ name +"': Circular reference - '"+
name +"' is a direct or indirect alias for '"+ alias +"' already");}}
exp 情况一 map key =A value = B 情况二 B C
name = B alias = A 现在传入 C A
publicbooleanhasAlias(String name, String alias){for(Map.Entry<String, String> entry :this.aliasMap.entrySet()){
String registeredName = entry.getValue();//Bif(registeredName.equals(name)){//B=B
String registeredAlias = entry.getKey();//map.key = A
A == alias == A
情况一 :就会产生传过来的别名与实例名与现有关系是, 传来别名对应现有实例名,传来实例名对应现有别名
if(registeredAlias.equals(alias)||
情况二 :走到这里时 registeredAlias = B alias = A 变成情况一返回truehasAlias(registeredAlias, alias)){returntrue;}}}returnfalse;}
根据给定name查该name下的所有别名
privatevoidretrieveAliases(String name, List<String> result){this.aliasMap.forEach((alias, registeredName)->{if(registeredName.equals(name)){
result.add(alias);retrieveAliases(alias, result);}});}