/**别名处理流程**/
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);
}
});
}
Spring学习-SimpleAliasRegistry
最新推荐文章于 2024-06-05 19:54:05 发布
本文详细解析了Spring框架中如何通过SimpleAliasRegistry处理别名注册的过程。包括如何使用ConcurrentHashMap来存储别名与实际名称的映射关系,并讨论了在并发环境下为避免循环引用而采取的同步措施。
523

被折叠的 条评论
为什么被折叠?



