/**
   * Executes Grails bootstrap classes
   *
   * @param application The Grails ApplicationContext instance
   * @param webContext The WebApplicationContext instance
   * @param servletContext The ServletContext instance
   */
  public static void executeGrailsBootstraps(
      GrailsApplication application,
      WebApplicationContext webContext,
      ServletContext servletContext) {

    PersistenceContextInterceptor interceptor = null;
    String[] beanNames = webContext.getBeanNamesForType(PersistenceContextInterceptor.class);
    if (beanNames.length > 0) {
      interceptor = (PersistenceContextInterceptor) webContext.getBean(beanNames[0]);
    }

    if (interceptor != null) {
      interceptor.init();
    }
    // init the Grails application
    try {
      GrailsClass[] bootstraps = application.getArtefacts(BootstrapArtefactHandler.TYPE);
      for (GrailsClass bootstrap : bootstraps) {
        final GrailsBootstrapClass bootstrapClass = (GrailsBootstrapClass) bootstrap;
        final Object instance = bootstrapClass.getReferenceInstance();
        webContext
            .getAutowireCapableBeanFactory()
            .autowireBeanProperties(instance, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
        bootstrapClass.callInit(servletContext);
      }
      if (interceptor != null) {
        interceptor.flush();
      }
    } finally {
      if (interceptor != null) {
        interceptor.destroy();
      }
    }
  }
  @Override
  public void destroy() {
    WebApplicationContext webContext = getWebApplicationContext();
    GrailsApplication grailsApplication =
        webContext.getBean(GrailsApplication.APPLICATION_ID, GrailsApplication.class);

    GrailsClass[] bootstraps = grailsApplication.getArtefacts(BootstrapArtefactHandler.TYPE);
    for (GrailsClass bootstrap : bootstraps) {
      ((GrailsBootstrapClass) bootstrap).callDestroy();
    }
    super.destroy();
  }