Register shutDownHook in web application Register shutDownHook in web application spring spring

Register shutDownHook in web application


registerShutdownHook() in standalone (non-web) application:

The @PreDestroy annotation is used on bean method to be notified when the bean is being removed from the context or when the context is shutting down.

Shut down event is fired when context.close() or context.registerShutdownHook() is invoked.

@Component(value="someBean")public class SomeBean {    @PreDestroy    public void destroy() {        System.out.println("Im inside destroy...");    }}

I hope you already know this.


registerShutdownHook() in web application:

In a web application, DispatcherServlet/ContextListener creates the ApplicationContext and it will close the context when the server shutdown. You don't need to explicitly invoke context.close() or context.registerShutdownHook().

When the server shutdown, @PreDestory methods on your bean will be notified automatically.


In web applications, you can use a ServletContextListener which fires when your application is deployed and undeployed:

public class MyServletContextListener implements ServletContextListener {    public void contextInitialized(ServletContextEvent sce) {        //application is being deployed    }    public void contextDestroyed(ServletContextEvent sce) {        //application is being undeployed    }}

You can access to your Spring beans by retrieving the current Spring context:

public void contextDestroyed(ServletContextEvent sce) {    ServletContext ctx = sce.getServletContext();    WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(ctx);    //retrieve your Spring beans here...    SomeSpringBean bean = (SomeSpringBean)ctx.getBean("someSprinbgBean");    //...}


Using Spring 3+ you can add a ContextCleanupListener to the application context.

Register your listener at startup like so (you might prefer to use xml config but the same applies)

package com.myappimport javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRegistration;import org.springframework.web.WebApplicationInitializer;import org.springframework.web.context.ContextCleanupListener;import org.springframework.web.context.ContextLoaderListener;import org.springframework.web.context.WebApplicationContext;import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;import org.springframework.web.servlet.DispatcherServlet;public class MyWebApplicationInitializer implements WebApplicationInitializer {    @Override    public void onStartup(ServletContext servletContext)            throws ServletException {        WebApplicationContext appContext = getContext();        servletContext.addListener(new ContextLoaderListener(appContext));        // line adding an implementation of ContextCleanupListener        servletContext.addListener(new MyWebApplicationCleanupListener());        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(appContext));            dispatcher.setLoadOnStartup(1);            dispatcher.addMapping("/");    }    private AnnotationConfigWebApplicationContext getContext() {         AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();        context.setConfigLocation("com.myapp");        return context;    }} 

Implementation of ContextCleanupListener that runs your shutdown code:

package com.myapp;import javax.servlet.ServletContextEvent;import com.myapp.resources.requiring.clean.shutdownimport org.springframework.web.context.ContextCleanupListener;public class MyWebApplicationCleanupListener extends ContextCleanupListener {    @Override    public void contextDestroyed(ServletContextEvent event) {        // put your shutdown code in here        MyResourceNeedingShutdown dataStore = MyResourceNeedingShutdown.getInstance();        dataStore.shutdown();    }}

When you run up say tomcat for example, and press CTRL + C to shut it down, you'll immediately see the contextDestroyed method be hit in the debugger if you put a breakpoint there.