In the post Spring Bean Life Cycle we have already seen that you can provide destroy methods for your beans to do clean up. One problem is that these destroy callback methods are not executed automatically you do have to call AbstractApplicationContext.destroy or AbstractApplicationContext.close before shutting down the IOC container. There is another option to ensure graceful shutdown, you can register a shutdown hook with the JVM using registerShutdownHook() method in Spring.
Note that this problem is only with non-web applications. Spring’s web-based ApplicationContext implementations already have code in place to shut down the Spring IoC container gracefully when the relevant web application is shut down.
registerShutdownHook() method in Spring
In Java programming language you can create shutdown hooks, where you create a new thread and provide logic that is executed when the JVM is shutting down. Then you can register your thread class instance as a shutdown hook to the VM using Runtime.getRuntime().addShutdownHook(Thread class instance); method.
That is what Spring framework does in the registerShutdownHook() method, it spawns a new thread and in the run() method of the thread call doClose() method. You can check the code in AbstractApplicationContext class.
public void registerShutdownHook() { if (this.shutdownHook == null) { // No shutdown hook registered yet. this.shutdownHook = new Thread() { @Override public void run() { doClose(); } }; Runtime.getRuntime().addShutdownHook(this.shutdownHook); } }
doClose() method in turn calls destroyBeans() method to destroy all cached singletons in the context and closeBeanFactory() method to close the state of the context itself. That ensures a graceful shutdown and calls the relevant destroy methods on your singleton beans so that all resources are released.
Spring registerShutdownHook() method example
There is a class PayServiceImpl which has initialization and destroy methods (methods annotated with @PostConstruct and @PreDestroy).
import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; public class PayServiceImpl implements IPayService{ private IPayment payment; private int amount; public PayServiceImpl(){ } public PayServiceImpl(IPayment payment){ this.payment = payment; } public void performPayment() { System.out.println("performPayment Method called"); } @PostConstruct public void initMethod(){ System.out.println("Calling InitMethod for PayServiceImpl"); } @PreDestroy public void destroyMethod(){ System.out.println("Calling destroyMethod"); } public IPayment getPayment() { return payment; } public void setPayment(IPayment payment) { this.payment = payment; } }
XML Configuration
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" /> <bean id="payServiceBean" class="org.netjs.exp.Spring_Example.PayServiceImpl"> </bean> </beans>
Class used to run the code, note that registerShutdownHook(); method is used at the end that will ensure that the destroy method is called.
import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { public static void main( String[] args ){ AbstractApplicationContext context = new ClassPathXmlApplicationContext ("appcontext.xml"); IPayService payBean = (IPayService)context.getBean("payServiceBean"); context.registerShutdownHook(); } }
Output
Calling InitMethod for PayServiceImpl Mar 14, 2018 10:30:33 AM org.springframework.context.support.ClassPathXmlApplicationContext doClose INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@6193b845: startup date [Wed Mar 14 10:30:32 IST 2018]; root of context hierarchy Calling destroyMethod
That's all for this topic registerShutdownHook() Method in Spring Framework. If you have any doubt or any suggestions to make please drop a comment. Thanks!
>>>Return to Spring Tutorial Page
Related Topics
You may also like-
No comments:
Post a Comment