Spring - Receiving Lifecycle callbacks by using @PostConstruct and @PreDestroy

[Last Updated: Mar 14, 2021]

Spring provides various mechanisms for getting bean lifecycle callbacks. These callbacks are useful to take some specific action at a particular lifecycle stage. It's specially needed at the point when bean is fully initialized and all properties are set.

Following are the differents ways to receive callbacks after bean has initialized and before bean is destroyed:

  1. Using @PostConstruct and @PreDestroy
  2. Using 'initMethod' and 'destroyMethod' of @Bean annotation.
  3. By implementing InitializingBean and DisposableBean

This tutorial shows the example of @PostConstruct and @PreDestroy. The next two tutorials will show other methods of receiving callbacks.

Using @PostConstruct and @PreDestroy

The recommended way to receive initialization/destruction callbacks is by using @PostConstruct and @PreDestroy annotations

package com.logicbig.example;

public class OtherBean {
package com.logicbig.example;

import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class MyBean {
  private OtherBean otherBean;

  public MyBean() {
      System.out.println("MyBean constructor: " + this);

  public void myPostConstruct() {

  public void setOtherBean(OtherBean otherBean) {
      System.out.println("setOtherBean(): " + otherBean);
      this.otherBean = otherBean;

  public void doSomething() {

  public void cleanUp() {
      System.out.println("cleanUp method");

In above example, we used setter injection, we can instead use field/constructor injection as well, the fields will be fully initialized the time when @PostConstruct method is called.

package com.logicbig.example;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

public class LifeCycleExample {

  public MyBean myBean() {
      return new MyBean();

  public OtherBean otherBean() {
      return new OtherBean();

  public static void main(String[] args) {
      ConfigurableApplicationContext context =
              new AnnotationConfigApplicationContext(LifeCycleExample.class);


      System.out.println("-- accessing bean --");
      MyBean bean = context.getBean(MyBean.class);

      System.out.println("-- finished --");


MyBean constructor: com.logicbig.example.MyBean@11a4dac4
setOtherBean(): com.logicbig.example.OtherBean@121394b8
-- accessing bean --
-- finished --
cleanUp method

Understanding registerShutdownHook() method

In above example, we used ConfigurableApplicationContext#registerShutdownHook(). This method registers a shutdown hook with the JVM runtime. This hook receives notification on JVM shutdown, at that time it closes the underlying context and calls all @PreDestroy and other standard register destroy methods. If we don't want to use this method then we have to call ConfigurableApplicationContext#close() ourselves at JVM shutdown, otherwise our destroy methods won't get called.

Initialization and destruction lifecycle callbacks Select All Download
  • spring-lifecycle-callbacks-using-annotation
    • src
      • main
        • java
          • com
            • logicbig
              • example

    See Also