AliasRegistry接口的简单实现。
用作BeanDefinitionRegistry实现的基类。
public class SimpleAliasRegistry implements AliasRegistry {
//使用Map保存别名与规范名称一一对应的关系
//第一个String是别名,第二个String是规范名称
private final Map<String, String> aliasMap =
new ConcurrentHashMap<String, String>(16);
//为给定规范名称name生成一个别名alias,并注册到aliasMap中
public void registerAlias(String name, String alias) {
//保证参数name不是""," "和null
//如果是,则提示'name' must not be empty
Assert.hasText(name, "'name' must not be empty");
//保证参数alias不是""," "和null
//如果是,则提示'alias' must not be empty
Assert.hasText(alias, "'alias' must not be empty");
//如果alias与name相等,则从aliasMap删除alias
if (alias.equals(name)) {
//删除,这里是一种覆盖的操作,所以不要使用已经
//存在的别名,这样会造成覆盖的效果
this.aliasMap.remove(alias);
//如果alias与name不等
}else {
//判断alias是否在aliasMap中
//如果在,获取值registeredName
String registeredName = this.aliasMap.get(alias);
//如果registeredName != null
//说明别名alias在aliasMap中
if (registeredName != null) {
//如果值registeredName与name相等
if (registeredName.equals(name)) {
//直接return,不支持重复注册
return;
}
//如果!allowAliasOverriding()结果为true
//抛出IllegalStateException异常以及异常提示信息
if (!allowAliasOverriding()) {
throw new IllegalStateException
("Cannot register alias '" + alias + "' for name '" +
name + "': It is already registered for name '" +
registeredName + "'.");
}
//!allowAliasOverriding()默认为false
}
//判断是否存在别名引用循环
//如果存在,则抛出IllegalStateException异常
//具体参考方法hasAlias(String name, String alias)
checkForAliasCircle(name, alias);
//将别名-规范名称键值对添加进Map中
this.aliasMap.put(alias, name);
}
}
//这个方法的作用就是返回true
protected boolean allowAliasOverriding() {
//默认返回true
return true;
}
//判断是否存在别名引用循环
public boolean hasAlias(String name, String alias) {
//foreach循环遍历整个Map
for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) {
//获取Map的值
String registeredName = entry.getValue();
//判断值与给定的name是否相等
if (registeredName.equals(name)) {
//如果相等,进一步获取键
String registeredAlias = entry.getKey();
//判断是否存在相互引用
return (registeredAlias.equals(alias) ||
//继续使用递归判断是否存在循环引用
hasAlias(registeredAlias, alias));
}
}
//如果以上情况都不存在,直接返回false
return false;
}
//删除指定的别名
public void removeAlias(String alias) {
//通过指定的别名获取值
String name = this.aliasMap.remove(alias);
//如果值为null
if (name == null) {
//抛出IllegalStateException异常
//并提示指定别名未注册
throw new IllegalStateException
("No alias '" + alias + "' registered");
}
}
//判断指定别名是否注册
public boolean isAlias(String name) {
//返回Map是否包含指定别名
return this.aliasMap.containsKey(name);
}
//返回指定规范名称的所有有关别名
public String[] getAliases(String name) {
//创建一个ArrayList对象
List<String> result = new ArrayList<String>();
//线程安全的访问Map
synchronized (this.aliasMap) {
//参考方法retrieveAliases
//(String name, List<String> result)
retrieveAliases(name, result);
}
//通过StringUtils.toStringArray(List list)
//将List转换成String[]后返回
return StringUtils.toStringArray(result);
}
//将指定名称name的别名添加到List中
private void retrieveAliases(String name, List<String> result) {
//foreach循环遍历整个Map
for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) {
//获取值
String registeredName = entry.getValue();
//如果值与给定name相等
if (registeredName.equals(name)) {
//继续获取键
String alias = entry.getKey();
//将键添加至List中
result.add(alias);
//递归继续寻找相关的别名
retrieveAliases(alias, result);
}
}
}
//解析所有别名目标名称和在此工厂中注册的别名
//将给定的StringValueResolver应用于它们
//例如,值解析器可以解析目标Bean名称甚至别名中的占位符
public void resolveAliases(StringValueResolver valueResolver) {
//保证解析器不为null
Assert.notNull(valueResolver,
"StringValueResolver must not be null");
//线程安全的访问Map
synchronized (this.aliasMap) {
//通过aliasMap重新创建一个aliasCopy
Map<String, String> aliasCopy =
new HashMap<String, String>(this.aliasMap);
//foreach循环遍历整个Map的key
for (String alias : aliasCopy.keySet()) {
//获取每个键的值
String registeredName = aliasCopy.get(alias);
//通过解析器valueResolver解析键alias
//返回结果resolvedAlias
String resolvedAlias =
valueResolver.resolveStringValue(alias);
//通过解析器valueResolver解析值registeredName
//返回结果resolvedName
String resolvedName =
valueResolver.resolveStringValue(registeredName);
//如果解析后的别名,规范名称为null或者是两者相等
if (resolvedAlias == null || resolvedName == null ||
resolvedAlias.equals(resolvedName)) {
//直接删除
this.aliasMap.remove(alias);
//如果解析后的别名与原先的别名不相等
}else if (!resolvedAlias.equals(alias)) {
//将解析后的别名作为键获取值,看是否已经注册
String existingName = this.aliasMap.get(resolvedAlias);
//如果值不为null,说明已经注册
if (existingName != null) {
//如果值与解析后的值相等,说明解析后的别名已经注册
//则不能重复注册
if (existingName.equals(resolvedName)) {
//直接删除原先的别名,因为解析它的结果已经存在了
//没必须要重复解析
this.aliasMap.remove(alias);
//中断循环
break;
}
//抛出IllegalStateException异常和提示信息
//表示这个别名不能重复注册
throw new IllegalStateException
("Cannot register resolved alias '" +
resolvedAlias + "' (original: '" + alias +
"') for name '" + resolvedName + "':
It is already registered for name '" +
registeredName + "'.");
}
//判断是否存在别名引用循环
//如果存在,则抛出IllegalStateException异常
//具体参考方法hasAlias(String name, String alias)
checkForAliasCircle(resolvedName, resolvedAlias);
//如果解析后的结果正常,将解析前的别名直接删除
this.aliasMap.remove(alias);
//添加解析后的别名和规范名称
this.aliasMap.put(resolvedAlias, resolvedName);
//如果解析后的别名和解析前的别名相同但是规范名称不同
}else if (!registeredName.equals(resolvedName)) {
//重新添加,覆盖解析前的规范名称
this.aliasMap.put(alias, resolvedName);
}
}
}
}
//判断是否存在别名的循环引用
protected void checkForAliasCircle(String name, String alias) {
//参考方法hasAlias(String name, String alias)
if (hasAlias(alias, name)) {
//如果存在别名循环引用,则抛出IllegalStateException异常
//以及提示信息
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) {
//保存name的值
String canonicalName = name;
//定义一个String类型的变量
String resolvedName;
//do-while循环
do {
//获取以canonicalName为键的值
resolvedName = this.aliasMap.get(canonicalName);
//如果值不为null
if (resolvedName != null) {
//赋值
canonicalName = resolvedName;
}
}
//如果值不为null
while (resolvedName != null);
//返回值
return canonicalName;
}
}