AliasRegistry接口定义了alias的基本操作。
package org.springframework.core; public interface AliasRegistry { //对指定的名称注册别名 void registerAlias(String name, String alias); //从当前容器移除指定别名 void removeAlias(String alias); //判断指定名称是否为别名 boolean isAlias(String beanName); //返回指定名称的所有别名 String[] getAliases(String name); }
SimpleAliasRegistry
SimpleAliasRegistry类对AliasRegistry进行了实现,其中使用了Map对alias进行缓存。
public class SimpleAliasRegistry implements AliasRegistry { /** Map from alias to canonical name,使用ConcurrentHashMap缓存别名与名称的映射关系key= 别名,value=beanName */ private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>(16);
registerAlias():
为指定名称注册别名,有以下几步:
1、校验输入参数。
2、不允许别名与指定名称一致,且移除已注册列表中该别名(不管已注册列表中是否存在该别名)。
3、如别名已注册则不再重复注册,根据是否允许覆盖条件判断是否抛出异常。
4、递归检查指定名称与别名是否存在环形指向关联关系。
5、注册别名。
@Override public void registerAlias(String name, String alias) { Assert.hasText(name, "'name' must not be empty"); Assert.hasText(alias, "'alias' must not be empty"); //如果名称和别名相同,则移除别名 if (alias.equals(name)) { 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; } //如果别名不允许被覆盖则抛异常, if (!allowAliasOverriding()) { throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'."); } } //递归检查别名 checkForAliasCircle(name, alias); //注册别名 this.aliasMap.put(alias, name); } }
因为SimpleAliasRegistry根据名称获取别名列表时,会将直接、间接关系的别名均列出来,所以注册别名时不允许名称与别名见存在环形指向关联关系。
//检查给定的名称是否已经指向给定的别名作为另一个方向的别名,在前面捕获一个循环引用并引发相应的IllegalstateException。 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"); } } //遍历+递归 public boolean hasAlias(String name, String alias) { for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) { String registeredName = entry.getValue(); if (registeredName.equals(name)) { String registeredAlias = entry.getKey(); return (registeredAlias.equals(alias) || hasAlias(registeredAlias, alias)); } } return false; }
移除别名、检查指定名称是被定义为别名。
根据指定名称获取所有别名,递归检索,其中包含直接指向的别名与间接指向的别名。