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
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.
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.
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.
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.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With