spring SimpleAliasRegistry 分析

SimpleAliasRegistry 是AliasRegistry 第一个接口实现

里面有些方法,和数据还是有必要说一下

private final Map<String, String> aliasMap = new ConcurrentHashMap(16);

 

public void registerAlias(String name, String alias) {
    Assert.hasText(name, "'name' must not be empty");
    Assert.hasText(alias, "'alias' must not be empty");
    Map var3 = this.aliasMap;
    synchronized(this.aliasMap) {
        if (alias.equals(name)) {
            this.aliasMap.remove(alias);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Alias definition '" + alias + "' ignored since it points to same name");
            }
        } else {
            String registeredName = (String)this.aliasMap.get(alias);
            if (registeredName != null) {
                if (registeredName.equals(name)) {
                    return;
                }

                if (!this.allowAliasOverriding()) {
                    throw new IllegalStateException("Cannot define alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'.");
                }

                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Overriding alias '" + alias + "' definition for registered name '" + registeredName + "' with new target name '" + name + "'");
                }
            }

            this.checkForAliasCircle(name, alias);
            this.aliasMap.put(alias, name);
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Alias definition '" + alias + "' registered for name '" + name + "'");
            }
        }

    }
}

 

public boolean hasAlias(String name, String alias) {
    Iterator var3 = this.aliasMap.entrySet().iterator();

    String registeredAlias;
    do {
        Entry entry;
        String registeredName;
        do {
            if (!var3.hasNext()) {
                return false;
            }

            entry = (Entry)var3.next();
            registeredName = (String)entry.getValue();
        } while(!registeredName.equals(name));

        registeredAlias = (String)entry.getKey();
    } while(!registeredAlias.equals(alias) && !this.hasAlias(registeredAlias, alias));

    return true;
}

1,为什么 Map 已经线程安全,但还是要 加synchronized控制,因为 Map只能保证map 这个容器线程安全,不能保证其他步骤,座椅有必要加一个(参考

2.checkForAliasCircle 检查是否循环注册 map.put(1,2)map.put(2,1),这就是循环注册依赖

他是两层循环

最里面的判断条件    !registeredName.equals(name)

这里的name 是之前的 alias,最开始传入参数的时候,倒置了一下 

while(!registeredAlias.equals(alias) && !this.hasAlias(registeredAlias, alias));

这里要说一下外层判断条件 !this.hasAlias(registeredAlias, alias)

当我传入

1,2

然后传入 3,1时候 第一个条件不成了,他会继续判断 (2,3)(1,3)这里可有不明白

2,3     2,3 

1,2            1,2           

3,1             3,1          3,1

1,3             1,3

 

 

这里判断是否已经存在这样的数据,构成一个循环,这样设计还是很巧妙的

public String[] getAliases(String name) {
    List<String> result = new ArrayList();
    Map var3 = this.aliasMap;
    synchronized(this.aliasMap) {
        this.retrieveAliases(name, result);
    }

    return StringUtils.toStringArray(result);
}

 

private void retrieveAliases(String name, List<String> result) {
    this.aliasMap.forEach((alias, registeredName) -> {
        if (registeredName.equals(name)) {
            result.add(alias);
            this.retrieveAliases(alias, result);
        }

    });
}

这里他会把涉及到 name 的 Aliases 全部找出来,并且还有关于Aliases【*】 相关的数据罗列出

 

 

public void resolveAliases(StringValueResolver valueResolver) {}

这个方法是通过lambda,来过滤别名

public String canonicalName(String name) {}

找到链式的最后一个数据  1

 

registry.registerAlias("1","2");
registry.registerAlias("5","1");

System.out.println(registry.canonicalName("2"));

输出5

    原文作者:Spring Boot
    原文地址: https://blog.csdn.net/qq_33291307/article/details/86663959
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞