public void destroy() {
    WebApplicationContext webContext = getWebApplicationContext();
    GrailsApplication application =
        (GrailsApplication)
            webContext.getBean(GrailsApplication.APPLICATION_ID, GrailsApplication.class);

    GrailsClass[] bootstraps = application.getArtefacts(BootstrapArtefactHandler.TYPE);
    for (int i = 0; i < bootstraps.length; i++) {
      ((GrailsBootstrapClass) bootstraps[i]).callDestroy();
    }
    super.destroy();
  }
  /**
   * Overrides the default behaviour to establish the handler from the GrailsApplication instance
   *
   * @param request The request
   * @param cache Whether to cache the Handler in the request
   * @return The HandlerExecutionChain
   * @throws Exception
   */
  protected HandlerExecutionChain getHandler(HttpServletRequest request, boolean cache)
      throws Exception {
    String uri = urlHelper.getPathWithinApplication(request);
    if (logger.isDebugEnabled()) {
      logger.debug("Looking up Grails controller for URI [" + uri + "]");
    }
    GrailsControllerClass controllerClass =
        (GrailsControllerClass)
            application.getArtefactForFeature(ControllerArtefactHandler.TYPE, uri);
    final String actionName =
        (String) request.getAttribute(GrailsApplicationAttributes.ACTION_NAME_ATTRIBUTE);

    if (controllerClass != null) {
      HandlerInterceptor[] interceptors;
      // if we're in a development environment we want to re-establish interceptors just in case
      // they
      // have changed at runtime

      if (GrailsUtil.isDevelopmentEnv()) {
        interceptors = establishInterceptors(getWebApplicationContext());
      } else {
        interceptors = this.interceptors;
      }
      if (controllerClass.isFlowAction(actionName)) {
        FlowHandler flowHandler =
            new AbstractFlowHandler() {
              public String getFlowId() {
                return actionName;
              }
            };
        return new HandlerExecutionChain(flowHandler, interceptors);
      } else {
        return new HandlerExecutionChain(mainController, interceptors);
      }
    }
    return null;
  }