Mastering Graceful Shutdown in Spring Boot: Hooks, Events, and @PreDestroy
Learn how to implement graceful shutdown in Spring Boot by understanding the JVM shutdown hook, customizing cleanup logic with ContextClosedEvent listeners and @PreDestroy annotations, and configuring the spring.main.register-shutdown-hook property to ensure resources are released safely during application termination.
When developing and deploying Spring Boot applications, graceful shutdown is crucial for releasing resources, completing tasks, and preventing data loss.
1. What is the Spring Boot shutdown hook?
Spring Boot can register a JVM shutdown hook based on the spring.main.register-shutdown-hook property (default true). The relevant code in SpringApplication looks like:
// ... existing code ...
if (this.properties.isRegisterShutdownHook()) {
SpringApplication.shutdownHook.enableShutdownHookAddition();
}
// ... existing code ...The property spring.main.register-shutdown-hook determines whether Spring Boot registers a shutdown hook that triggers when the JVM receives a normal termination signal (e.g., Ctrl+C, kill <pid>), allowing the application to shut down gracefully.
2. How to customize cleanup logic?
Spring Boot offers two recommended ways to run custom cleanup code when the application stops:
2.1 Listen to ContextClosedEvent
This approach integrates with the Spring application context lifecycle. Implement ApplicationListener<ContextClosedEvent>, register the class as a Spring bean, and place the cleanup code in onApplicationEvent:
// src/main/java/com/dosun/demo01/listener/MyCleanupListener.java
package com.dosun.demo01.listener;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.stereotype.Component;
@Component
public class MyCleanupListener implements ApplicationListener<ContextClosedEvent> {
@Override
public void onApplicationEvent(ContextClosedEvent event) {
System.out.println("Application context closed. Executing custom cleanup...");
// 1. Close DB connections
// 2. Release file handles
// 3. Shut down thread pools
// 4. Clear caches, etc.
System.out.println("Custom cleanup completed.");
}
}2.2 Use @PreDestroy annotation
For a specific Spring‑managed bean, annotate a method with @PreDestroy. The method runs before the bean is destroyed:
// src/main/java/com/dosun/demo01/service/MyService.java
package com.dosun.demo01.service;
import org.springframework.stereotype.Service;
import jakarta.annotation.PreDestroy;
@Service
public class MyService {
public MyService() {
System.out.println("MyService bean created.");
}
@PreDestroy
public void cleanup() {
System.out.println("MyService bean is being destroyed. Performing bean‑level cleanup...");
// Custom cleanup logic, e.g., close internal connections
System.out.println("MyService cleanup finished.");
}
public void doSomething() {
System.out.println("MyService is doing work.");
}
}3. What happens if spring.main.register-shutdown-hook is set to false?
When the property is false, Spring Boot does not register the JVM shutdown hook. Consequently, normal termination signals (such as Ctrl+C or kill) will not trigger the Spring context shutdown, and listeners for ContextClosedEvent will not be invoked.
Methods annotated with @PreDestroy are still called if the application context is closed programmatically (e.g., via SpringApplication.exit() or ApplicationContext.close()). However, in typical scenarios where the process is stopped by an OS signal, the @PreDestroy methods will not run, leading to potential resource leaks.
If true (default): Spring registers the JVM shutdown hook, ensuring both ContextClosedEvent listeners and @PreDestroy methods execute during graceful termination.
If false: The shutdown hook is omitted; normal OS signals bypass Spring’s shutdown process, so cleanup logic tied to the hook may not run, risking unreleased resources and data inconsistency.
Therefore, keeping spring.main.register-shutdown-hook enabled is strongly recommended for production environments to achieve reliable and clean application shutdown.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Tech Enthusiast
Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
