How to Gracefully Shut Down a Spring Boot Application: 5 Proven Methods

Learn five practical ways to gracefully shut down a Spring Boot application—including using Actuator’s shutdown endpoint, closing the application context, PID file handling, SpringApplication.exit, and a custom shutdown controller—so unfinished tasks finish, logs flush, and services stop safely without resorting to kill‑9.

Programmer DD
Programmer DD
Programmer DD
How to Gracefully Shut Down a Spring Boot Application: 5 Proven Methods

When stopping a Spring Boot service, many developers simply use kill -9, which prevents graceful shutdown and may leave unfinished tasks. This article presents five methods to stop a Spring Boot application safely, ensuring pending work completes, logs are flushed, and signals are sent to dependent systems.

Method 1: Actuator Shutdown Endpoint

Add the Actuator dependency and enable the shutdown endpoint in application.properties:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
server.port=3333
management.endpoint.shutdown.enabled=true
management.endpoints.web.exposure.include=shutdown

Create a bean with a @PreDestroy method to log when the bean is destroyed:

package com.hqs.springboot.shutdowndemo.bean;

import javax.annotation.PreDestroy;

public class TerminateBean {
    @PreDestroy
    public void preDestroy() {
        System.out.println("TerminateBean is destroyed");
    }
}

Expose the bean via a configuration class:

package com.hqs.springboot.shutdowndemo.config;

import com.hqs.springboot.shutdowndemo.bean.TerminateBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ShutDownConfig {
    @Bean
    public TerminateBean getTerminateBean() {
        return new TerminateBean();
    }
}

Start the application and trigger shutdown with:

curl -X POST http://localhost:3333/actuator/shutdown

Method 2: Close Application Context

Obtain the ConfigurableApplicationContext from SpringApplication.run and close it after a delay:

/* method 2: use ctx.close to shutdown all application context */
ConfigurableApplicationContext ctx = SpringApplication.run(ShutdowndemoApplication.class, args);
try {
    TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
    e.printStackTrace();
}
ctx.close();

Method 3: PID File and External Kill

Generate a PID file during startup and stop the process with a shell command:

/* method 3: generate a pid in a specified path, then kill it */
SpringApplication application = new SpringApplication(ShutdowndemoApplication.class);
application.addListeners(new ApplicationPidFileWriter("/Users/huangqingshi/app.pid"));
application.run();

Stop with:

cat /Users/huangqingshi/app.pid | xargs kill

Method 4: SpringApplication.exit()

Use SpringApplication.exit to obtain an exit code and then call System.exit:

/* method 4: exit this application using static method */
ConfigurableApplicationContext ctx = SpringApplication.run(ShutdowndemoApplication.class, args);
exitApplication(ctx);

public static void exitApplication(ConfigurableApplicationContext context) {
    int exitCode = SpringApplication.exit(context, () -> 0);
    System.exit(exitCode);
}

Method 5: Custom Shutdown Controller

Implement a controller that receives a shutdown request and closes the context:

package com.hqs.springboot.shutdowndemo.controller;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ShutDownController implements ApplicationContextAware {
    private ApplicationContext context;

    @PostMapping("/shutDownContext")
    public String shutDownContext() {
        ConfigurableApplicationContext ctx = (ConfigurableApplicationContext) context;
        ctx.close();
        return "context is shutdown";
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }
}

Trigger with:

curl -X POST http://localhost:3333/shutDownContext

Summary

All five methods are straightforward, but in production you must protect exposed endpoints (e.g., firewall or internal‑network restrictions) to maintain security. Method 3 is commonly used; when shutting down quickly, avoid heavy data operations to ensure the service stops promptly.

For the full source code, visit the Git repository: https://github.com/stonehqs/shutdowndemo.git.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaSpring BootGraceful ShutdownActuatorPreDestroy
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.