Spring之28:AliasRegistry&SimpleAliasRegistry

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;
    }
递归检查别名关联关系
检查name是否直接或间接关联alias

移除别名、检查指定名称是被定义为别名。

根据指定名称获取所有别名,递归检索,其中包含直接指向的别名与间接指向的别名。

根据指定名称获取别名列表
转:https://www.jianshu.com/p/45c36ff80770

原文地址:https://www.cnblogs.com/duanxz/p/3634656.html