Spring - Initialization and destruction lifecycle callbacks

[Updated: May 2, 2017, Created: May 2, 2017]

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.

Using @PostConstruct and @PreDestroy

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

public class MyBean {
  private OtherBean otherBean;

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

  @PostConstruct
  public void myPostConstruct() {
      System.out.println("myPostConstruct()");
  }

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

  public void doSomething() {
      System.out.println("doSomething()");
  }

  @PreDestroy
  public void cleanUp() {
      System.out.println("cleanUp method");
  }
}
public class MyBean2 {
  private OtherBean otherBean;

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

  public void myPostConstruct() {
      System.out.println("myPostConstruct()");
  }

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

  public void doSomething() {
      System.out.println("doSomething()");
  }

  public void cleanUp() {
      System.out.println("cleanUp method");
  }
}
@Configuration
public class LifeCycleExample {

  @Bean
  public MyBean myBean() {
      return new MyBean();
  }

  @Bean
  public OtherBean otherBean() {
      return new OtherBean();
  }

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

      context.registerShutdownHook();

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

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

Output

MyBean constructor: com.logicbig.example.MyBean@fde068a
setOtherBean(): com.logicbig.example.OtherBean@39b62948
myPostConstruct()
-- accessing bean --
doSomething()
-- 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.

Also, 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 get called.

Using 'initMethod' and 'destroyMethod' of @Bean annotation.

public class MyBean2 {
  private OtherBean otherBean;

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

  public void myPostConstruct() {
      System.out.println("myPostConstruct()");
  }
    .............
  public void cleanUp() {
      System.out.println("cleanUp method");
  }
}
@Configuration
public class LifeCycleExample2 {

  @Bean(initMethod = "myPostConstruct", destroyMethod = "cleanUp")
  public MyBean2 myBean2() {
      return new MyBean2();
  }
    .............
}

Output

MyBean2 constructor: com.logicbig.example.MyBean2@614592c9
setOtherBean(): com.logicbig.example.OtherBean@5f99afcd
myPostConstruct()
-- accessing bean --
doSomething()
-- finished --
cleanUp method

Implementing InitializingBean and DisposableBean

The interface InitializingBean has one method afterPropertiesSet which is get called by spring framework after it has set all bean properties.

The interface DisposableBean has one method destroy which is get called by spring framework when JVM sends the shutdown signal.

public class MyBean3 implements InitializingBean, DisposableBean {
  private OtherBean otherBean;

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

  @Override
  public void afterPropertiesSet() throws Exception {
      System.out.println("afterPropertiesSet()");
  }
    .............
  @Override
  public void destroy() throws Exception {
      System.out.println("destroy() method");
  }
}
@Configuration
public class LifeCycleExample3 {

  @Bean
  public MyBean3 myBean3() {
      return new MyBean3();
  }
    .............
}

Output

MyBean3 constructor: com.logicbig.example.MyBean3@1d4834fb
setOtherBean(): com.logicbig.example.OtherBean@130b5770
afterPropertiesSet()
-- accessing bean --
doSomething() :
-- finished --
destroy() method

Example Project

Dependencies and Technologies Used :

  • spring-context 4.3.8.RELEASE: Spring Context.
  • jopt-simple 5.0.3: A Java library for parsing command line options.
  • JDK 1.8
  • Maven 3.3.9

Lifecycle Callbacks Examples Select All Download
  • lifecycle-callbacks
    • src
      • main
        • java
          • com
            • logicbig
              • example

See Also