/**
   * Register the given bean definition with the given bean factory.
   *
   * @param bdHolder the bean definition including name and aliases
   * @param beanFactory the bean factory to register with
   * @throws BeansException if registration failed
   */
  public static void registerBeanDefinition(
      BeanDefinitionHolder bdHolder, BeanDefinitionRegistry beanFactory) throws BeansException {

    // Register bean definition under primary name.
    beanFactory.registerBeanDefinition(bdHolder.getBeanName(), bdHolder.getBeanDefinition());

    // Register aliases for bean name, if any.
    if (bdHolder.getAliases() != null) {
      for (int i = 0; i < bdHolder.getAliases().length; i++) {
        beanFactory.registerAlias(bdHolder.getBeanName(), bdHolder.getAliases()[i]);
      }
    }
  }
  /**
   * Generate a bean name for the given bean definition, unique within the given bean factory.
   *
   * @param beanDefinition the bean definition to generate a bean name for
   * @param beanFactory the bean factory that the definition is going to be registered with (to
   *     check for existing bean names)
   * @param isInnerBean whether the given bean definition will be registered as inner bean or as
   *     top-level bean (allowing for special name generation for inner beans vs. top-level beans)
   * @return the bean name to use
   * @throws BeanDefinitionStoreException if no unique name can be generated for the given bean
   *     definition
   */
  public static String generateBeanName(
      AbstractBeanDefinition beanDefinition,
      BeanDefinitionRegistry beanFactory,
      boolean isInnerBean)
      throws BeanDefinitionStoreException {

    String generatedId = beanDefinition.getBeanClassName();
    if (generatedId == null) {
      if (beanDefinition instanceof ChildBeanDefinition) {
        generatedId = ((ChildBeanDefinition) beanDefinition).getParentName() + "$child";
      } else if (beanDefinition.getFactoryBeanName() != null) {
        generatedId = beanDefinition.getFactoryBeanName() + "$created";
      }
    }
    if (!StringUtils.hasText(generatedId)) {
      throw new BeanDefinitionStoreException(
          beanDefinition.getResourceDescription(),
          "",
          "Unnamed bean definition specifies neither 'class' nor 'parent' nor 'factory-bean'"
              + " - can't generate bean name");
    }

    String id = generatedId;
    if (isInnerBean) {
      // Inner bean: generate identity hashcode suffix.
      id =
          generatedId
              + GENERATED_BEAN_NAME_SEPARATOR
              + ObjectUtils.getIdentityHexString(beanDefinition);
    } else {
      // Top-level bean: use plain class name. If not already unique,
      // add counter - increasing the counter until the name is unique.
      int counter = 0;
      while (beanFactory.containsBeanDefinition(id)) {
        counter++;
        id = generatedId + GENERATED_BEAN_NAME_SEPARATOR + counter;
      }
    }
    return id;
  }