Authors Top

If you have a few years of experience in the Java ecosystem, and you’d like to share that with the community, have a look at our Contribution Guidelines.

Spring Top – Temp

Get started with Spring 5 and Spring Boot 2, through the reference Learn Spring course:

>> LEARN SPRING
Lightrun – Third Party Code
announcement - icon

Flakiness in REST requests is a common issue. A request can get a 200 OK in one scenario and a 409 next time. Sometimes a request can even succeed and fail intermittently on the same exact request. In short, working over HTTP can be a bit of a mess without solid tooling.

Also, while it’s easy enough to debug these issues locally when developing the application, we’re talking about production here - we can’t afford the downtime while you’re stepping in and out of code. Uptime is kind of the whole point.

With Lightrun, you can get the same level of access you get with a local debugger or profiler - no downtime required. You can add logs, metrics, and snapshots (think breakpoints, but without stopping the running service), in a safe and read-only manner - without redeploying, restarting, or even stopping the running service. Performance and security are maintained throughout the process.

Learn how to debug a live REST API (built with Spring, of course), using Lightrun, in this 5-minute tutorial:

>> Debugging REST Requests in Spring-Based applications using the Lightrun Platform

1. Overview

In this tutorial, we're going to learn different ways to use shutdown callbacks with Spring.

The main advantage of using a shutdown callback is that it gives us control over a graceful application exit.

2. Shutdown Callback Approaches

Spring supports both the component-level and the context-level shutdown callbacks. We can create these callbacks using:

  • @PreDestroy
  • DisposableBean interface
  • Bean-destroy method
  • Global ServletContextListener

Let's see all of these approaches with examples.

2.1. Using @PreDestroy

Let's create a bean that uses @PreDestroy:

@Component
public class Bean1 {

    @PreDestroy
    public void destroy() {
        System.out.println(
          "Callback triggered - @PreDestroy.");
    }
}

During the bean initialization, Spring will register all the bean methods that are annotated with @PreDestroy and invokes them when the application shuts down.

2.2. Using the DisposableBean Interface

Our second bean will implement the DisposableBean interface to register the shutdown callback:

@Component
public class Bean2 implements DisposableBean {

    @Override
    public void destroy() throws Exception {
        System.out.println(
          "Callback triggered - DisposableBean.");
    }
}

2.3. Declaring a Bean Destroy Method

For this approach, firstly we'll create a class with a custom destroy method:

public class Bean3 {

    public void destroy() {
        System.out.println(
          "Callback triggered - bean destroy method.");
    }
}

Then, we create the configuration class that initializes the bean and marks its destroy() method as our shutdown callback:

@Configuration
public class ShutdownHookConfiguration {

    @Bean(destroyMethod = "destroy")
    public Bean3 initializeBean3() {
        return new Bean3();
    }
}

The XML way of registering the destroy method is:

<bean class="com.baeldung.shutdownhooks.config.Bean3"
  destroy-method="destroy">

2.4. Using a Global ServletContextListener

Unlike the other three approaches, which register the callback at bean level, the ServletContextListener registers the callback at context level.

For this let's create a custom context listener:

public class ExampleServletContextListener
  implements ServletContextListener {

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        System.out.println(
          "Callback triggered - ContextListener.");
    }

    @Override
    public void contextInitialized(ServletContextEvent event) {
        // Triggers when context initializes
    }
}

We need to register it to the ServletListenerRegistrationBean in the configuration class:

@Bean
ServletListenerRegistrationBean<ServletContextListener> servletListener() {
    ServletListenerRegistrationBean<ServletContextListener> srb
      = new ServletListenerRegistrationBean<>();
    srb.setListener(new ExampleServletContextListener());
    return srb;
}

3. Conclusion

We've learned about the different ways Spring provides to register shutdown callbacks, both at the bean level and at the context level.

These can be used for shutting down the application gracefully and effectively freeing up the used resources.

As always all the examples mentioned in this article can be found over on Github.

Spring bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> THE COURSE
Generic footer banner
Comments are closed on this article!