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("张三"), ","));
}
执行结果如下:
神枪手本名是张三
张三的别名有:神枪手,狗二
猎人本名是张三
张三的别名有:神枪手,猎人,狗二,全蛋,富士康质检员