Spring 系列目录(http://www.javashuo.com/article/p-kqecupyl-bm.html)html
public interface AliasRegistry { void registerAlias(String name, String alias); void removeAlias(String alias); boolean isAlias(String name); String[] getAliases(String name); }
AliasRegistry 接口十分简单,提供了注册、获取及删除指定 beanName 的别名的功能。下面咱们重点关注一下它的默认的实现 SimpleAliasRegistry。java
@Test public void test() { SimpleAliasRegistry aliasRegistry = new SimpleAliasRegistry(); aliasRegistry.registerAlias("beanA", "beanA_alias1"); aliasRegistry.registerAlias("beanA_alias1", "beanA_alias2"); // 1. 获取别名对应的真实名称 Assert.assertEquals("beanA", aliasRegistry.canonicalName("beanA_alias1")); Assert.assertEquals("beanA", aliasRegistry.canonicalName("beanA_alias2")); // 2. 获取 beanA 的全部别名 Assert.assertEquals(2, aliasRegistry.getAliases("beanA").length); Assert.assertTrue(aliasRegistry.isAlias("beanA_alias1")); Assert.assertTrue(aliasRegistry.hasAlias("beanA", "beanA_alias2")); }
(1) 属性spring
SimpleAliasRegistry 内部维护了一个队列,存储的是 <alais, name>api
private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);
(2) registerAliaside
注册一个 alias源码分析
@Override public void registerAlias(String name, String alias) { synchronized (this.aliasMap) { // 1. 别名和 bean 的名称相同,不须要注册,若是注册了也要删除 if (alias.equals(name)) { this.aliasMap.remove(alias); } else { String registeredName = this.aliasMap.get(alias); // 2. 别名已经注册,若是注册的名称不相同是否容许覆盖 if (registeredName != null) { if (registeredName.equals(name)) { return; } // 默认返回 true if (!allowAliasOverriding()) { throw new IllegalStateException(""); } } // 3. 注册前检查是否出现了循环注册,如注册 (a, b) 时已经注册了 (b, a) checkForAliasCircle(name, alias); this.aliasMap.put(alias, name); } } }
(3) hasAliasthis
判断指定的 name 是否有 alias 的别名。code
// a -> b -> c -> d -> e -> canonicalName,反向查找先找到最后一个 name // 而后一个一个判断是否是要查找的 alias 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(); if (registeredAlias.equals(alias) || hasAlias(registeredAlias, alias)) { return true; } } } return false; } // 检查循环依赖 protected void checkForAliasCircle(String name, String alias) { if (hasAlias(alias, name)) { throw new IllegalStateException(""); } }
(4) getAliaseshtm
获取指定 bean 的全部别名。blog
@Override public String[] getAliases(String name) { List<String> result = new ArrayList<>(); synchronized (this.aliasMap) { 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); retrieveAliases(alias, result); } }); }
(5) canonicalName
获取一个 alias 的真实 name。
public String canonicalName(String name) { String canonicalName = name; // Handle aliasing... String resolvedName; do { resolvedName = this.aliasMap.get(canonicalName); if (resolvedName != null) { canonicalName = resolvedName; } } while (resolvedName != null); return canonicalName; }
(5) resolveAliases
解析 alias 和 name 中的占位符。
public void resolveAliases(StringValueResolver valueResolver) { synchronized (this.aliasMap) { // 由于遍历时要修改 Map 集合,因此 copy 了一个新集合用于遍历 Map<String, String> aliasCopy = new HashMap<>(this.aliasMap); aliasCopy.forEach((alias, registeredName) -> { String resolvedAlias = valueResolver.resolveStringValue(alias); String resolvedName = valueResolver.resolveStringValue(registeredName); // 1. 不存在或 resolvedAlias=resolvedName 时直接干掉 if (resolvedAlias == null || resolvedName == null || resolvedAlias.equals(resolvedName)) { this.aliasMap.remove(alias); // 2. 别名解析后变化,两种状况:一是真实别名已经注册;二是没有注册。 // 真实别名已经注册又有两种状况:真实别名获取的 name 和要注册的 name 是否相等 } else if (!resolvedAlias.equals(alias)) { String existingName = this.aliasMap.get(resolvedAlias); // 2.1 别名已存在且相等只须要将含有占位符的别名删除便可,不然抛出异常 if (existingName != null) { if (existingName.equals(resolvedName)) { this.aliasMap.remove(alias); return; } throw new IllegalStateException(); } // 2.2 不存在,注册前一样须要检查循环依赖 checkForAliasCircle(resolvedName, resolvedAlias); this.aliasMap.remove(alias); this.aliasMap.put(resolvedAlias, resolvedName); // 3. 真实名称解析后变化直接替换 } else if (!registeredName.equals(resolvedName)) { this.aliasMap.put(alias, resolvedName); } }); } }
BeanDefinitionRegistry 管理全部注册在 BeanFactory 上的 BeanDefinitio
public interface BeanDefinitionRegistry extends AliasRegistry { // 1. BeanDefinition 的注册、删除、获取 void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException; void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; // 2. 其他的查询操做 boolean containsBeanDefinition(String beanName); String[] getBeanDefinitionNames(); int getBeanDefinitionCount(); // 3. BeanFactory 是否注册了这个 bean,最简单的办法是 isAlias(beanName) || containsBeanDefinition(beanName) boolean isBeanNameInUse(String beanName); }
BeanDefinitionRegistry 的默认实现为 SimpleBeanDefinitionRegistry,它的实现也十分简单,内部维护 Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(64) 的队列。
天天用心记录一点点。内容也许不重要,但习惯很重要!