Spring SimpleAliasRegistry源码解析

SimpleAliasRegistry

继承图

实现的接口

AliasRegistry

AliasRegistry主要用于别名注册,包含给beanName注册别名,删除别名,判断是否为别名,以及获取beanName对应的别名

/**
 * 用于管理别名的通用接口。 
 * 用作{@link  org.springframework.beans.factory.support.BeanDefinitionRegistry}的超级接口。 
 *  @author 于尔根·霍勒(Juergen Hoeller)@2.5.2起
 */
public interface AliasRegistry {

   /**
    * 给定名称,为其注册一个别名。 
    * @param name the canonical name(简洁的名字)
    * @param 别名 要注册的别名
    * @throws  IllegalStateException如果别名已在使用中并且可能不会被覆盖
    */
   void registerAlias(String name, String alias);

   /**
    * 从此注册表中删除指定的别名。 
    *  
    * @param alias 将要删除的别名
    * @throws  IllegalStateException 找不到别名
    */
   void removeAlias(String alias);

   /**
    * 确定给定名称是否被定义为别名(与实际注册的组件的名称相反)。 
    *  
    * @param name 要检查的名称
    * @return 给定名称是否为别名
    */
   boolean isAlias(String name);

   /**
    * 返回给定名称的别名(如果已定义)。 
    *  
    * @param name 要检查别名的bean的名称
    * @return 别名,如果没有则为空数组
    */
   String[] getAliases(String name);

}

解析

实现从aliasbeanName的映射(alias=》beanName),因为使用的是ConcurrentHashMap,而且一个beanName对应一个alias,所以把alias当key,beanName当value。

如果aliasbeanName相同,会打印出信息,并且不做映射。

特别注意alias不支持传递映射和循环映射。

/**
 * {@link  AliasRegistry}接口的简单实现。 
 *  <p>用作{@link  org.springframework.beans.factory.support.BeanDefinitionRegistry}实现的基类。 
 */
public class SimpleAliasRegistry implements AliasRegistry {

   /**
    * 从别名映射到canonical name。 
    */
   private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);

   /**
    * 给name注册alias
    * @param name bean的name
    * @param alias bean的alias
    */
   @Override
   public void registerAlias(String name, String alias) {
      Assert.hasText(name, "'name' must not be empty");
      Assert.hasText(alias, "'alias' must not be empty");
      synchronized (this.aliasMap) {
         if (alias.equals(name)) {
            this.aliasMap.remove(alias);
            if (logger.isDebugEnabled()) {
               logger.debug("Alias definition '" + alias + "' ignored since it points to same name");
            }
         }
         else {
            String registeredName = this.aliasMap.get(alias);
            if (registeredName != null) {
               if (registeredName.equals(name)) {
                  // An existing alias - no need to re-register
                  return;
               }
               if (!allowAliasOverriding()) {
                  throw new IllegalStateException("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);
            this.aliasMap.put(alias, name);
            if (logger.isTraceEnabled()) {
               logger.trace("Alias definition '" + alias + "' registered for name '" + name + "'");
            }
         }
      }
   }
   /**
    * 获得是否允许别名覆盖。 
    *  <p>默认值为{@code  true}。 
    */
   protected boolean allowAliasOverriding() {
      return true;
   }
    
   /**
    * 确定给定名称是否已注册给定别名。 
    *  
    * @param name 要检查的名称
    * @param alias 要查找的别名@since 4.2.1起的别名
    */
   public boolean hasAlias(String name, String alias) {
      String registeredName = this.aliasMap.get(alias);
       
        //for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) {
        //            String registeredName = entry.getValue();
        //            /**
        //            * 禁止的两种情况:
        //            *  1、map容器(carA:car),指定(carA,car),相同映射
        //            *  2、map容器(carA:car,carC:carA),指定(carC,car) 循环映射
        //            */
        //            if (registeredName.equals(name)) {
        //                String registeredAlias = entry.getKey();
        //                if (registeredAlias.equals(alias) || hasAlias(registeredAlias, alias)) {
        //                    return true;
        //                }
        //            }
        //        }
        //        return false;
        
       // 假设有 A-> B , C -> A传入 C B,那么
       // registeredName = A;
       // name = C
       // alias = B
       // ObjectUtils.nullSafeEquals(registeredName, name) 是 false
       // hasAlias(C, A)
       // name = C, alias = A
       // registeredName = C
       // return true
       // 即传递映射是不被允许的
      
       // 假设有 A-> B , C -> A传入 B C,那么
       // registeredName = A;
       // name = B
       // alias = C
       // ObjectUtils.nullSafeEquals(registeredName, name) 是false
       // hasAlias(B, A)
       // registeredName = A;
       // name = B
       // alias = A
       // return true
      return ObjectUtils.nullSafeEquals(registeredName, name) || (registeredName != null
            && hasAlias(name, registeredName));
   }

   @Override
   public void removeAlias(String alias) {
      synchronized (this.aliasMap) {
         String name = this.aliasMap.remove(alias);
         if (name == null) {
            throw new IllegalStateException("No alias '" + alias + "' registered");
         }
      }
   }
   /**
     * 确定是否给定的name是beanName的alias
     */
   @Override
   public boolean isAlias(String name) {
      return this.aliasMap.containsKey(name);
   }

    /**
      * 获得给定name的所有alias
      */
   @Override
   public String[] getAliases(String name) {
      List<String> result = new ArrayList<>();
      synchronized (this.aliasMap) {
         retrieveAliases(name, result);
      }
      return StringUtils.toStringArray(result);
   }

   /**
    * Transitively retrieve all aliases for the given name.
    * @param name the target name to find aliases for
    * @param result the resulting aliases list
    */
   /**
    * 递归检索给定名称的所有别名。 
    *  
    * @param name 查找的目标名称
    * @param result 查找的别名列表
    */
   private void retrieveAliases(String name, List<String> result) {
      this.aliasMap.forEach((alias, registeredName) -> {
         if (registeredName.equals(name)) {
            result.add(alias);
            retrieveAliases(alias, result);
         }
      });
   }
    
   /**
    * 解析所有别名目标名称和在此注册表中注册的别名,将给定的{@link  StringValueResolver}应用于它们。 
    *  <p>例如,值解析器可以解析目标Bean名称甚至别名中的占位符。 
    *  
    * @param  valueResolver 要应用的StringValueResolver
    */
   public void resolveAliases(StringValueResolver valueResolver) {
      Assert.notNull(valueResolver, "StringValueResolver must not be null");
      synchronized (this.aliasMap) {
         Map<String, String> aliasCopy = new HashMap<>(this.aliasMap);
         aliasCopy.forEach((alias, registeredName) -> {
            String resolvedAlias = valueResolver.resolveStringValue(alias);
            String resolvedName = valueResolver.resolveStringValue(registeredName);
            if (resolvedAlias == null || resolvedName == null || resolvedAlias.equals(resolvedName)) {
               this.aliasMap.remove(alias);
            }
            else if (!resolvedAlias.equals(alias)) {
               String existingName = this.aliasMap.get(resolvedAlias);
               if (existingName != null) {
                  if (existingName.equals(resolvedName)) {
                     // Pointing to existing alias - just remove placeholder
                     this.aliasMap.remove(alias);
                     return;
                  }
                  throw new IllegalStateException(
                        "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);
            }
            else if (!registeredName.equals(resolvedName)) {
               this.aliasMap.put(alias, resolvedName);
            }
         });
      }
   }

   /**
    * 检查给定名称是否已经作为另一个方向的别名指向给定别名,是否预先捕获了循环引用并引发了相应的IllegalStateException。 
    *  
    * @param name 候选名称
    * @param name 候选别名
    * @see  #registerAlias 
    * @see  #hasAlias
    */
   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");
      }
   }

   /**
    * Determine the raw name, resolving aliases to canonical names.
    * @param name the user-specified name
    * @return the transformed name
    */
   /**
    * 确定原始名称,将别名解析为规范名称。 
    *  
    * @param name 用户指定的名称
    * @return 转换后的名称
    */
   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;
   }

}

问题

为什么不允许循环依赖?

hasAlias()resolveAliases()代码看不懂

猜你喜欢

转载自www.cnblogs.com/akfak/p/12380645.html
今日推荐