SimpleAliasRegistry

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;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值