You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
publicinterfaceAliasRegistry { /** * 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 * @see SimpleAliasRegistry * @see org.springframework.context.support.GenericApplicationContext */voidregisterAlias(Stringname, Stringalias); /** * Remove the specified alias from this registry. * 别名移除 * * @param alias the alias to remove * @throws IllegalStateException if no such alias was found */voidremoveAlias(Stringalias); /** * 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 */booleanisAlias(Stringname); /** * Return the aliases for the given name, if defined. * 从别名注册map中获取别名信息 * * @param name the name to check for aliases * @return the aliases, or an empty array if none */String[] getAliases(Stringname); }
SimpleAliasRegistry
/** * Simple implementation of the {@link AliasRegistry} interface. * Serves as base class for * {@link org.springframework.beans.factory.support.BeanDefinitionRegistry} * implementations. * * @author Juergen Hoeller * @since 2.5.2 */publicclassSimpleAliasRegistryimplementsAliasRegistry { /** * Logger available to subclasses. */protectedfinalLoglogger = LogFactory.getLog(getClass()); /** * Map from alias to canonical name. * 存放别名的map(线程安全的), * 结构: alias-> name */privatefinalMap<String, String> aliasMap = newConcurrentHashMap<>(16); /** * {@code <alias name="appleBean" alias="hhh"/>} * * @param name the canonical name * alias 标签的name属性 * @param alias the alias to be registered * alias 标签的alias属性 */@OverridepublicvoidregisterAlias(Stringname, Stringalias) { Assert.hasText(name, "'name' must not be empty"); Assert.hasText(alias, "'alias' must not be empty"); synchronized (this.aliasMap) { // 判断: 别名和名字是否相同if (alias.equals(name)) { //相同在别名map中移除this.aliasMap.remove(alias); if (logger.isDebugEnabled()) { logger.debug("Alias definition '" + alias + "' ignored since it points to same name"); } } else { // 不相同// 从map对象中获取别名为alias的valueStringregisteredName = this.aliasMap.get(alias); if (registeredName != null) { // 判断map中是否有有一个别名和传入的name相同的内容if (registeredName.equals(name)) { // An existing alias - no need to re-registerreturn; } if (!allowAliasOverriding()) { thrownewIllegalStateException("Cannot define alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'."); } if (logger.isDebugEnabled()) { logger.debug("Overriding alias '" + alias + "' definition for registered name '" + registeredName + "' with new target name '" + name + "'"); } } // 别名环检查checkForAliasCircle(name, alias); // 放入 map 对象中 alias-> namethis.aliasMap.put(alias, name); if (logger.isTraceEnabled()) { logger.trace("Alias definition '" + alias + "' registered for name '" + name + "'"); } } } } /** * Return whether alias overriding is allowed. * Default is {@code true}. * 是否允许重写别名 */protectedbooleanallowAliasOverriding() { returntrue; } /** * Determine whether the given name has the given alias registered. * <p> * 递归判断是否已经存在别名 * * @param name the name to check * @param alias the alias to look for * @since 4.2.1 */publicbooleanhasAlias(Stringname, Stringalias) { for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) { // 获取key值StringregisteredName = entry.getValue(); if (registeredName.equals(name)) { StringregisteredAlias = entry.getKey(); // 循环引用判断if (registeredAlias.equals(alias) || hasAlias(registeredAlias, alias)) { returntrue; } } } returnfalse; } /** * 别名移除 * * @param alias the alias to remove */@OverridepublicvoidremoveAlias(Stringalias) { synchronized (this.aliasMap) { // 判断是否移除成功Stringname = this.aliasMap.remove(alias); if (name == null) { thrownewIllegalStateException("No alias '" + alias + "' registered"); } } } /** * 判断是否是一个别名,校验方式{@link org.springframework.core.SimpleAliasRegistry#aliasMap} 的key是否包含 * * @param name the name to check * @return */@OverridepublicbooleanisAlias(Stringname) { returnthis.aliasMap.containsKey(name); } /** * 获取别名列表 * * @param name the name to check for aliases * @return */@OverridepublicString[] getAliases(Stringname) { List<String> result = newArrayList<>(); synchronized (this.aliasMap) { retrieveAliases(name, result); } returnStringUtils.toStringArray(result); } /** * Transitively retrieve all aliases for the given name. * 根据 name 获取别名 * * @param name the target name to find aliases for * @param result the resulting aliases list */privatevoidretrieveAliases(Stringname, List<String> result) { // 循环获取this.aliasMap.forEach((alias, registeredName) -> { if (registeredName.equals(name)) { result.add(alias); // 递归查询循环引用的别名retrieveAliases(alias, result); } }); } /** * Resolve all alias target names and aliases registered in this * factory, applying the given StringValueResolver to them. * <p>The value resolver may for example resolve placeholders * in target bean names and even in alias names. * * @param valueResolver the StringValueResolver to apply */publicvoidresolveAliases(StringValueResolvervalueResolver) { Assert.notNull(valueResolver, "StringValueResolver must not be null"); synchronized (this.aliasMap) { Map<String, String> aliasCopy = newHashMap<>(this.aliasMap); aliasCopy.forEach((alias, registeredName) -> { StringresolvedAlias = valueResolver.resolveStringValue(alias); StringresolvedName = valueResolver.resolveStringValue(registeredName); if (resolvedAlias == null || resolvedName == null || resolvedAlias.equals(resolvedName)) { this.aliasMap.remove(alias); } elseif (!resolvedAlias.equals(alias)) { StringexistingName = this.aliasMap.get(resolvedAlias); if (existingName != null) { if (existingName.equals(resolvedName)) { // Pointing to existing alias - just remove placeholderthis.aliasMap.remove(alias); return; } thrownewIllegalStateException( "Cannot register resolved alias '" + resolvedAlias + "' (original: '" + alias + "') for name '" + resolvedName + "': It is already registered for name '" + registeredName + "'."); } checkForAliasCircle(resolvedName, resolvedAlias); this.aliasMap.remove(alias); this.aliasMap.put(resolvedAlias, resolvedName); } elseif (!registeredName.equals(resolvedName)) { this.aliasMap.put(alias, resolvedName); } }); } } /** * Check whether the given name points back to the given alias as an alias * in the other direction already, catching a circular reference upfront * and throwing a corresponding IllegalStateException. * <p> * 判断是否循环别名 * * @param name the candidate name * @param alias the candidate alias * @see #registerAlias * @see #hasAlias */protectedvoidcheckForAliasCircle(Stringname, Stringalias) { if (hasAlias(alias, name)) { thrownewIllegalStateException("Cannot register alias '" + alias + "' for name '" + name + "': Circular reference - '" + name + "' is a direct or indirect alias for '" + alias + "' already"); } } /** * Determine the raw name, resolving aliases to canonical names. * * @param name the user-specified name * @return the transformed name */publicStringcanonicalName(Stringname) { StringcanonicalName = name; // Handle aliasing...StringresolvedName; do { resolvedName = this.aliasMap.get(canonicalName); if (resolvedName != null) { canonicalName = resolvedName; } } while (resolvedName != null); returncanonicalName; } }