Spring源码(一):管理别名Alias不再麻烦[AliasRegistry]

作者: jekkay 分类: java,默认 发布时间: 2019-04-10 10:51

Spring源码(一):管理别名Alias不再麻烦[AliasRegistry]


一· 概述

我们会经常碰到一个别名管理的问题,比如一个域名有多个IP,又有多个别域名,而别域名又有很多与之对应的别域名,如此循环。如何快速地找到对应关系,是一件比较麻烦的事情。

在Spring的bean管理容器中,也存在这样类似的问题,因为bean可以取很多别名,别名又可以有别名等。为此,Spring专门提供了一个接口AliasRegistry来实现此功能。

二· 接口说明

AliasRegistry定义如下,其中必须也仅有一个名字为本名(canonical name),其他都为别名。

原文地址: http://www.easysb.cn

public interface AliasRegistry {

    /**
     * Given a name, register an alias for it.
     * @param name the canonical name
     * @param alias the alias to be registered
     * @throws IllegalStateException if the alias is already in use
     * and may not be overridden
     */
    void registerAlias(String name, String alias);

    /**
     * Remove the specified alias from this registry.
     * @param alias the alias to remove
     * @throws IllegalStateException if no such alias was found
     */
    void removeAlias(String alias);

    /**
     * Determine whether this given name is defines as an alias
     * (as opposed to the name of an actually registered component).
     * @param name the name to check
     * @return whether the given name is an alias
     */
    boolean isAlias(String name);

    /**
     * Return the aliases for the given name, if defined.
     * @param name the name to check for aliases
     * @return the aliases, or an empty array if none
     */
    String[] getAliases(String name);

}

上面的接口很简单,直接看函数名就知道功能,就不做赘述了。Spring内部也提供了一个实现类SimpleAliasRegistry,其内部就是通过Map实现的。

原文地址: http://www.easysb.cn

public class SimpleAliasRegistry implements AliasRegistry {

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

三· 快速使用

可以直接使用SimpleAliasRegistry来管理别名。一个本名可以注册多个别名,别名也可以注册多个另外的别名。

  • 注意1: 注册别名,不能出现循环,不然会报错
  • 注意2: 不能将不同的名字叫同一个别名,后者将覆盖掉前者
原文地址: http://www.easysb.cn

    @Test
    public void useAlias() {
        // 别名的引用查找例子
        // 生命一个别名的注册容器,内部是直接通过Map<String, String>实现类似有向树的结构拓扑
        // 其中必须有且只有一个canonical name,可以简单理解为唯一的本名
        SimpleAliasRegistry aliasRegistry = new SimpleAliasRegistry();

        // 注册一个别名,比如张三的小名就狗二,张三就是本名
        aliasRegistry.registerAlias("张三", "狗二");
        // 张三还有一个别名,叫 神枪手
        aliasRegistry.registerAlias("张三", "神枪手");

        // 此时,如果获取神枪手,就是张三了
        System.out.println("神枪手本名是" + aliasRegistry.canonicalName("神枪手"));
        // 获取一下张三的所有别名
        System.out.println("张三的别名有:" + StringUtils.join(aliasRegistry.getAliases("张三"), ","));

        // 别名的别名
        // 有人管 狗二 就 全蛋
        aliasRegistry.registerAlias("狗二", "全蛋");
        // 有人管 全蛋 叫 富士康质检员
        aliasRegistry.registerAlias("全蛋", "富士康质检员");
        // 有人管 神枪手 叫 猎人
        aliasRegistry.registerAlias("神枪手", "猎人");
        // 不能循取别名
        // aliasRegistry.registerAlias("猎人", "神枪手"); // 报错
        // aliasRegistry.registerAlias("猎人", "张三");  // 报错

        // 不能将不同的名字叫同一个别名,会将之前的覆盖掉。比如两个别名设置,守夜人就会覆盖猎人,
        // 会割裂了 张三 与 矮人火枪手 的联系,导致 张三的别名中没有 矮人火枪手
        // aliasRegistry.registerAlias("猎人", "矮人火枪手");
        // aliasRegistry.registerAlias("守夜人", "矮人火枪手");

        // 此时,如果获取猎人,就是张三了
        System.out.println("猎人本名是" + aliasRegistry.canonicalName("猎人"));
        // 获取一下张三的所有别名
        System.out.println("张三的别名有:" + StringUtils.join(aliasRegistry.getAliases("张三"), ","));
    }

执行结果如下:

神枪手本名是张三
张三的别名有:神枪手,狗二
猎人本名是张三
张三的别名有:神枪手,猎人,狗二,全蛋,富士康质检员

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。