Spring学习-SimpleAliasRegistry

/**别名处理流程**/
org.springframework.core.SimpleAliasRegistry#registerAlias

/** Map from alias to canonical name */
	别名到实例名的映射
	private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);

@Override
	public void registerAlias(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-register
						return;
					}
					是否允许别名重写,默认true
					if (!allowAliasOverriding()) {
						throw new IllegalStateException("Cannot define alias '" + alias + "' for name '" +
								name + "': It is already registered for name '" + registeredName + "'.");
					}
				}
				检查别名循环引用问题  不允许别名循环依赖 
				checkForAliasCircle(name, alias);
				存入别名
				this.aliasMap.put(alias, name);
			}
		}
	}


protected void checkForAliasCircle(String name, String alias) {
		if (hasAlias(alias, name)) {
			throw new IllegalStateException("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
	
public boolean hasAlias(String name, String alias) {
		for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) {
			String registeredName = entry.getValue();//B
			if (registeredName.equals(name)) { //B=B 
				String registeredAlias = entry.getKey(); //map.key = A 
				A == alias == A 
			情况一 :就会产生传过来的别名与实例名与现有关系是, 传来别名对应现有实例名,传来实例名对应现有别名
				if (registeredAlias.equals(alias) || 
				情况二 :走到这里时 registeredAlias = B    alias  = A  变成情况一返回true 
				hasAlias(registeredAlias, alias)) {
					return true;
				}
			}
		}
		return false;
	}

根据给定name查该name下的所有别名
private void retrieveAliases(String name, List<String> result) {
		this.aliasMap.forEach((alias, registeredName) -> {
			if (registeredName.equals(name)) {
				result.add(alias);
				retrieveAliases(alias, result);
			}
		});
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值