In Spring, the lifecycle of a bean can be managed, and you can hook into these lifecycle phases using annotations like @PostConstruct
and @PreDestroy
.
@PostConstruct
:- This annotation is part of Jakarta annotations (not proprietary to Spring).
- It is used to execute initialization logic after the bean’s properties have been set (i.e., after dependency injection is complete).
@PreDestroy
:- This annotation is also part of Jakarta annotations.
- It is used to define a clean-up method that Spring calls before the bean is destroyed, typically during application shutdown.
To use these annotations in a Spring-managed bean:
Example with a Spring Bean:
package org.kodejava.spring;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
public MyBean() {
System.out.println("MyBean constructor called");
}
@PostConstruct
public void init() {
System.out.println("MyBean @PostConstruct called: Initialization logic here");
}
@PreDestroy
public void destroy() {
System.out.println("MyBean @PreDestroy called: Cleanup logic here");
}
}
Explanation:
- Constructor: When the bean is instantiated by Spring, the constructor is called.
@PostConstruct
(Initialization logic): Once the bean is instantiated and its dependencies are injected, this annotated method is invoked automatically.@PreDestroy
(Cleanup logic): Before the bean is destroyed (typically when the application context is being closed), this annotated method is invoked automatically.
Notes:
- Newer versions of Spring Boot automatically include this dependency.
- If you’re working on Spring Boot, your application supports these lifecycle callbacks out of the box.
Alternative for Lifecycle Management:
You can also achieve similar functionality using Spring’s InitializingBean
and DisposableBean
interfaces or by explicitly configuring init and destroy methods in the bean definitions.
package org.kodejava.spring;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
@Component
public class MyBean implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("MyBean initializing using InitializingBean");
}
@Override
public void destroy() throws Exception {
System.out.println("MyBean destroying using DisposableBean");
}
}
However, using @PostConstruct
and @PreDestroy
is generally preferred because they are more concise and not tightly coupled to Spring APIs.
Maven Dependencies
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.2.6</version>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>