protected void initXmlApplicationContext(
     AcServiceConfig serviceConfig, boolean autoScan, Resource... configResources) {
   GenericXmlApplicationContext xmlContext = new GenericXmlApplicationContext();
   appContext = xmlContext;
   xmlContext.setParent(prepareParentContext(serviceConfig));
   xmlContext.load(configResources);
   if (autoScan) {
     ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(xmlContext);
     // scan this package from provider hosting
     scanner.scan(this.getClass().getPackage().getName());
   }
   postSetupApplicationContext(appContext, serviceConfig);
   appContext.refresh();
 }
  public static List<Object> scan(ApplicationContext applicationContext, String... basePackages) {
    GenericApplicationContext genericAppContext = new GenericApplicationContext();
    ClassPathBeanDefinitionScanner scanner =
        new ClassPathBeanDefinitionScanner(genericAppContext, false);

    scanner.addIncludeFilter(new AnnotationTypeFilter(RestService.class));
    scanner.scan(basePackages);
    genericAppContext.setParent(applicationContext);
    genericAppContext.refresh();

    List<Object> restResources =
        new ArrayList<>(genericAppContext.getBeansWithAnnotation(RestService.class).values());

    return restResources;
  }
  /**
   * Register a {@link BeanDefinition} for each class specified by {@link #getConfigLocations()}, or
   * scan each specified package for annotated classes. Enables the default set of annotation
   * configuration post processors, such that {@literal @Autowired}, {@literal @Required}, and
   * associated annotations can be used.
   *
   * <p>Configuration class bean definitions are registered with generated bean definition names
   * unless the {@literal value} attribute is provided to the stereotype annotation.
   *
   * @see #getConfigLocations()
   * @see AnnotatedBeanDefinitionReader
   * @see ClassPathBeanDefinitionScanner
   */
  @Override
  protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
    AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(beanFactory);
    ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(beanFactory);
    BeanNameGenerator beanNameGenerator = getBeanNameGenerator();
    ScopeMetadataResolver scopeMetadataResolver = getScopeMetadataResolver();
    if (beanNameGenerator != null) {
      reader.setBeanNameGenerator(beanNameGenerator);
      scanner.setBeanNameGenerator(beanNameGenerator);
    }
    if (scopeMetadataResolver != null) {
      reader.setScopeMetadataResolver(scopeMetadataResolver);
      scanner.setScopeMetadataResolver(scopeMetadataResolver);
    }

    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
      for (String configLocation : configLocations) {
        try {
          Class<?> clazz = getClassLoader().loadClass(configLocation);
          if (logger.isInfoEnabled()) {
            logger.info("Successfully resolved class for [" + configLocation + "]");
          }
          reader.register(clazz);
        } catch (ClassNotFoundException ex) {
          if (logger.isDebugEnabled()) {
            logger.debug(
                "Could not load class for config location ["
                    + configLocation
                    + "] - trying package scan. "
                    + ex);
          }
          int count = scanner.scan(configLocation);
          if (logger.isInfoEnabled()) {
            if (count == 0) {
              logger.info(
                  "No annotated classes found for specified class/package ["
                      + configLocation
                      + "]");
            } else {
              logger.info(
                  "Found " + count + " annotated classes in package [" + configLocation + "]");
            }
          }
        }
      }
    }
  }
  private void parseGrailsApplication(
      Element element,
      ParserContext parserContext,
      XmlReaderContext readerContext,
      ClassLoader beanClassLoader,
      String[] basePackages) {

    BeanDefinitionRegistry simpleRegistry = new SimpleBeanDefinitionRegistry();
    ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, simpleRegistry);

    scanner.scan(basePackages);

    BeanDefinitionRegistry targetRegistry = parserContext.getRegistry();
    AbstractBeanDefinition grailsApplicationBean = new GenericBeanDefinition();
    grailsApplicationBean.setBeanClass(DefaultGrailsApplication.class);
    grailsApplicationBean.setInitMethodName("initialise");
    ConstructorArgumentValues constructorArgs =
        grailsApplicationBean.getConstructorArgumentValues();

    Set<Class<?>> classes = new HashSet<Class<?>>();
    for (String beanName : simpleRegistry.getBeanDefinitionNames()) {
      BeanDefinition beanDef = simpleRegistry.getBeanDefinition(beanName);
      try {
        Class<?> entityClass = Class.forName(beanDef.getBeanClassName(), true, beanClassLoader);
        classes.add(entityClass);
        registerDomainBean(
            entityClass, targetRegistry, element.getAttribute(MESSAGE_SOURCE_ATTRIBUTE));
      } catch (ClassNotFoundException e) {
        throw new BeanDefinitionParsingException(
            new Problem(
                "Unable to load class whilst configuring GORM: " + e.getMessage(),
                new Location(readerContext.getResource()),
                null,
                e));
      }
    }

    constructorArgs.addGenericArgumentValue(classes.toArray(new Class[classes.size()]));
    constructorArgs.addGenericArgumentValue(beanClassLoader);
    targetRegistry.registerBeanDefinition(GrailsApplication.APPLICATION_ID, grailsApplicationBean);
  }
  private ClassPathBeanDefinitionScanner configureScanner(
      ParserContext parserContext, BeanDefinitionRegistry registry) {
    XmlReaderContext readerContext = parserContext.getReaderContext();
    // Delegate bean definition registration to scanner class.
    ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, false);
    scanner.setIncludeAnnotationConfig(false);
    scanner.addIncludeFilter(new AnnotationTypeFilter(Entity.class));

    scanner.setResourceLoader(readerContext.getResourceLoader());
    scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
    scanner.setAutowireCandidatePatterns(
        parserContext.getDelegate().getAutowireCandidatePatterns());

    return scanner;
  }