/**
   * Returns the name of the Bean as registered to Spring. Throws IllegalState exception if none or
   * more than one beans are found.
   *
   * @param ctx spring application context
   * @param clazz bean class
   * @param required true if the value is required
   * @throws IllegalStateException
   * @return spring name of the bean
   */
  private String getBeanNameOfClass(
      final ApplicationContext ctx, final Class<?> clazz, final boolean required) {
    // get the list of all possible matching beans
    List<String> names =
        new ArrayList<String>(
            Arrays.asList(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(ctx, clazz)));

    // filter out beans that are not candidates for autowiring
    if (ctx instanceof AbstractApplicationContext) {
      Iterator<String> it = names.iterator();
      while (it.hasNext()) {
        final String possibility = it.next();
        BeanDefinition beanDef =
            getBeanDefinition(((AbstractApplicationContext) ctx).getBeanFactory(), possibility);
        if (BeanFactoryUtils.isFactoryDereference(possibility)
            || possibility.startsWith("scopedTarget.")
            || (beanDef != null && !beanDef.isAutowireCandidate())) {
          it.remove();
        }
      }
    }

    if (names.isEmpty()) {
      if (required) {
        throw new IllegalStateException("bean of type [" + clazz.getName() + "] not found");
      }
      return null;
    } else if (names.size() > 1) {
      if (ctx instanceof AbstractApplicationContext) {
        List<String> primaries = new ArrayList<String>();
        for (String name : names) {
          BeanDefinition beanDef =
              getBeanDefinition(((AbstractApplicationContext) ctx).getBeanFactory(), name);
          if (beanDef instanceof AbstractBeanDefinition) {
            if (beanDef.isPrimary()) {
              primaries.add(name);
            }
          }
        }
        if (primaries.size() == 1) {
          return primaries.get(0);
        }
      }
      StringBuilder msg = new StringBuilder();
      msg.append("More than one bean of type [");
      msg.append(clazz.getName());
      msg.append("] found, you have to specify the name of the bean ");
      msg.append(
          "(@SpringBean(name=\"foo\")) or (@Named(\"foo\") if using @javax.inject classes) in order to resolve this conflict. ");
      msg.append("Matched beans: ");
      msg.append(Strings.join(",", names.toArray(new String[names.size()])));
      throw new IllegalStateException(msg.toString());
    } else {
      return names.get(0);
    }
  }
 private BeanDefinitionHolder getDataSourceBeanDefinition(
     ConfigurableListableBeanFactory beanFactory) {
   String[] beanNames = beanFactory.getBeanNamesForType(DataSource.class);
   if (ObjectUtils.isEmpty(beanNames)) {
     logger.warn("No DataSource beans found, " + "embedded version will not be used");
   }
   if (beanNames.length == 1) {
     String beanName = beanNames[0];
     BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
     return new BeanDefinitionHolder(beanDefinition, beanName);
   }
   for (String beanName : beanNames) {
     BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
     if (beanDefinition.isPrimary()) {
       return new BeanDefinitionHolder(beanDefinition, beanName);
     }
   }
   logger.warn("No primary DataSource found, " + "embedded version will not be used");
   return null;
 }