spring源码阅读之SimpleAliasRegistry

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】

org.springframework.core.SimpleAliasRegistry.java 是一个关于spring注册别名的java类

重要变量:

    /** Map from alias to canonical name */ private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);

方法解读:

首先从注册方法入手:

    @Override
    public void registerAlias(String name, String alias)

注册考虑并发情况,增加同步锁

    synchronized (this.aliasMap) 

alias和name必须不相同才会注册进aliasMap,否则不成功

    if (alias.equals(name)) {
       this.aliasMap.remove(alias);

当name与当前alias的别名注册过的name不相同时,默认不允许覆盖,并抛出异常

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

这里存在一个方法去防止注册循环,之后重点学习下

    checkForAliasCircle(name, alias);

通过循环注册验证后,完成注册

    this.aliasMap.put(alias, name);

现在看一下

    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,并判断registedAlias是否等于等待注册的alias,如果是,则返回true;如果相等,递归循环判断是否存在真名a的别名为b,b的别名为c,如果最初的参数为(a,c)这样环形引用的情况返回的是true.猜测:也就是说,在获取别名时,b和c都是a的alias,那么使用b和c作为别名,都可以获得相同的真名!验证:

    public String canonicalName(String name) 
    do {
       resolvedName = this.aliasMap.get(canonicalName);
       if (resolvedName != null) {
          canonicalName = resolvedName;
       }
    }
    while (resolvedName != null);

这里的循环判断正是处理这种循环引用的,以达到别名的别名也可以引用canonicalName.

获取alias,因为可能存在读写冲突,所以在筛选alias结果集的时候,需要同步

    public String[] getAliases(String name)
    synchronized (this.aliasMap) {
       retrieveAliases(name, result);
    }
    this.aliasMap.forEach((alias, registeredName) -> {
       if (registeredName.equals(name)) {
          result.add(alias);
          retrieveAliases(alias, result);
       }
    });

这里也是处理循环引用的方式,通过canonicalName可以获取所有别名包括别名的别名.

之后还有一个方法:

    public void resolveAliases(StringValueResolver valueResolver)

这个方法主要存储格式化处理后的name和alias


来源:[]()

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » spring源码阅读之SimpleAliasRegistry

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏