实现了AliasRegistry接口,用ConcurrentHashMap存储别名的对应关系,别名做为key,name做为value。segmentfault
注册别名数组
@Override public void registerAlias(String name, String alias) { Assert.hasText(name, "'name' must not be empty"); Assert.hasText(alias, "'alias' must not be empty"); synchronized (this.aliasMap) { //若是别名和name同样,则移除这个别名。 if (alias.equals(name)) { this.aliasMap.remove(alias); if (logger.isDebugEnabled()) { logger.debug("Alias definition '" + alias + "' ignored since it points to same name"); } } 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 define alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'."); } if (logger.isDebugEnabled()) { logger.debug("Overriding alias '" + alias + "' definition for registered name '" + registeredName + "' with new target name '" + name + "'"); } } //判断是否循环 checkForAliasCircle(name, alias); this.aliasMap.put(alias, name); if (logger.isTraceEnabled()) { logger.trace("Alias definition '" + alias + "' registered for name '" + name + "'"); } } } }
返回是否容许别名覆盖ide
protected boolean allowAliasOverriding() { // 默认容许覆盖 return true; }
是否有别名,这里要判断循环依赖。this
public boolean hasAlias(String name, String alias) { for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) { //获取注册名称 String registeredName = entry.getValue(); if (registeredName.equals(name)) {//若是注册名称跟当前name同样 String registeredAlias = entry.getKey(); //若是equals为true,说明循环依赖了 //若是为false,再调用hasAlias,好比a,b一组,b,c一组,此时c,a,多个循环依赖了 if (registeredAlias.equals(alias) || hasAlias(registeredAlias, alias)) { return true; } } } return false; }
移除别名spa
public void removeAlias(String alias) { synchronized (this.aliasMap) { String name = this.aliasMap.remove(alias); // 没有对应的别名,抛异常 if (name == null) { throw new IllegalStateException("No alias '" + alias + "' registered"); } } }
是否存在别名debug
public boolean isAlias(String name) { // 直接在aliasMap里判断 return this.aliasMap.containsKey(name); }
根据bean名称获取别名code
public String[] getAliases(String name) { List<String> result = new ArrayList<>(); synchronized (this.aliasMap) { // 主要的方法 retrieveAliases(name, result); } // 把List转数组 return StringUtils.toStringArray(result); }
获取别名的实际方法,根据别名递归查找,直至找到全部的别名。blog
private void retrieveAliases(String name, List<String> result) { this.aliasMap.forEach((alias, registeredName) -> { if (registeredName.equals(name)) { //若是注册名和当前name同样,用对应的别名,继续查找 //好比a,b一组,b,c一组,咱们想获取a的别名,找到b后,会用b继续查找,找到c,此时,获得的值就是b、c result.add(alias); retrieveAliases(alias, result); } }); }
public void resolveAliases(StringValueResolver valueResolver) { Assert.notNull(valueResolver, "StringValueResolver must not be null"); synchronized (this.aliasMap) { Map<String, String> aliasCopy = new HashMap<>(this.aliasMap); aliasCopy.forEach((alias, registeredName) -> { // 获取解析后的别名 String resolvedAlias = valueResolver.resolveStringValue(alias); // 获取解析后的注册名 String resolvedName = valueResolver.resolveStringValue(registeredName); // 为空或者两个相等,移除掉 if (resolvedAlias == null || resolvedName == null || resolvedAlias.equals(resolvedName)) { this.aliasMap.remove(alias); } else if (!resolvedAlias.equals(alias)) { // 别名和解析后的别名不同 // 获取注册名 String existingName = this.aliasMap.get(resolvedAlias); // 若是存在 if (existingName != null) { // 获取到的就是解析后的注册名,就把别名对应的移除。若是不同,说明解析后的注册名被占用了,就抛异常 if (existingName.equals(resolvedName)) { // Pointing to existing alias - just remove placeholder this.aliasMap.remove(alias); return; } throw new IllegalStateException( "Cannot register resolved alias '" + resolvedAlias + "' (original: '" + alias + "') for name '" + resolvedName + "': It is already registered for name '" + registeredName + "'."); } //判断是否循环 checkForAliasCircle(resolvedName, resolvedAlias); // 移除alias并设置解析后的映射 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,循环调用抛异常 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"); } }
经过别名查找最原始的注册名,好比a,b一组,b,c一组。
咱们调用的参数是c,第一次循环,resolvedName为b,canonicalName为b,resolvedName不为空,会继续第二次循环,resolvedName为a,canonicalName为a,resolvedName不为空,第三次循环,resolvedName为空,canonicalName依然为a,跳出循环,返回a。接口
public String canonicalName(String name) { String canonicalName = name; // Handle aliasing... String resolvedName; do { resolvedName = this.aliasMap.get(canonicalName); if (resolvedName != null) { canonicalName = resolvedName; } } while (resolvedName != null); return canonicalName; }