Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Register shutDownHook in web application

How we can registerShutdown hook in web application?

Is there any whays to register it in web.xml or in applicationContext.xml?

I know that if we are using application with main class it's simple.

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
    context.registerShutdownHook();

But what about web application? As it uses ContextListener

like image 548
slisnychyi Avatar asked May 29 '14 14:05

slisnychyi


People also ask

How do you handle a shut down LOC container?

If you use Spring's IoC container in a non-web application environment (for example, in a rich client desktop environment), register a shutdown hook with the JVM. Doing so ensures a graceful shutdown and calls the relevant destroy methods on your singleton beans so that all resources are released.

What is Register shutdown hook in Spring?

The registerShutdownHook() is a method of Spring AbstractApplicationContext class. 2. The registerShutdownHook() method registers a shutdown hook named SpringContextShutdownHook with the JVM runtime. 3. On calling registerShutdownHook() , the Spring context is closed on JVM shutdown, if not already closed.

How do you install a shutdown hook in a Spring boot?

Each SpringApplication will register a shutdown hook with the JVM to ensure that the ApplicationContext is closed gracefully on exit. All the standard Spring lifecycle callbacks (such as the DisposableBean interface, or the @PreDestroy annotation) can be used. In addition, beans may implement the org. springframework.


3 Answers

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.

like image 172
Kalyan Avatar answered Oct 25 '22 22:10

Kalyan


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");
    //...
}
like image 24
Luiggi Mendoza Avatar answered Oct 25 '22 23:10

Luiggi Mendoza


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.myapp

import 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.shutdown
import 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.

like image 25
John Deverall Avatar answered Oct 25 '22 22:10

John Deverall