Introduction
Imagine planting a seed in your garden. You don’t just throw it in the soil and expect magic. You prepare the ground, water it, nurture it, watch it grow, and eventually remove it when its purpose is fulfilled. Surprisingly, Spring works in a very similar way. Every object that Spring manages goes through its own controlled journey—from creation to destruction. This is called the Spring Bean lifecycle.
If you're learning Spring Boot or advancing your Java programming skills, understanding this lifecycle is essential. It helps you create cleaner, safer, and more predictable systems. In this blog, we’ll break the lifecycle down into simple steps, explain why it matters, walk through examples, and share practical best practices.
Core Concepts
In Spring, every dependency-managed object is called a Spring Bean. These beans are created, injected, initialized, used, and destroyed by the Spring IoC container automatically.
This lifecycle consists of multiple stages, each with a purpose.
Let’s visualize the lifecycle like a human journey:
✔ born
✔ prepared
✔ equipped
✔ used
✔ retired
1) Bean Instantiation
Spring creates a new instance of your class.
2) Dependency Injection
Spring injects the required dependencies into your bean:
- Constructor injection
- Setter injection
- Field injection
3) Aware Interfaces (optional)
If implemented, the bean gains access to:
- bean name
- BeanFactory
- ApplicationContext
Examples:
BeanNameAwareApplicationContextAware
4) BeanPostProcessor
Spring applies pre-init and post-init logic.
Useful for:
- logging
- audits
- AOP
- monitoring
5) Initialization Callbacks
Two common methods:
✔ @PostConstruct
✔ InitializingBean.afterPropertiesSet()
This is preparation logic.
6) Bean Usage
The bean is active and serving requests.
7) Destruction Callbacks
Triggered when Spring context shuts down.
Handled through:
✔ @PreDestroy
✔ DisposableBean.destroy()
This is cleanup logic.
Why does the lifecycle matter?
Because it enables developers to:
- prepare resources safely
- avoid memory leaks
- manage heavy beans
- clean up properly
- log system behavior precisely
In enterprise Java programming, this becomes extremely valuable.
Code Examples
Example 1 — Using @PostConstruct and @PreDestroy
package com.example.lifecycle;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.springframework.stereotype.Component;
@Component
public class EmailService {
@PostConstruct
public void init() {
System.out.println("EmailService initialized.");
}
public void sendMail() {
System.out.println("Sending email...");
}
@PreDestroy
public void shutdown() {
System.out.println("EmailService shutdown invoked.");
}
}
Example 2 — Using InitializingBean & DisposableBean
package com.example.lifecycle;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
@Component
public class DatabaseConnection
implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() {
System.out.println("Database connected.");
}
@Override
public void destroy() {
System.out.println("Database connection closed.");
}
}
Best Practices
✔ Prefer @PostConstruct / @PreDestroy over interface methods
✔ Keep init/destroy logic lightweight
✔ Avoid business logic inside lifecycle hooks
✔ Always release external resources (DB, MQ, sockets, cache)
✔ Test lifecycle behavior during integration testing
Conclusion
The Spring Bean lifecycle is a sequence of steps that every bean goes through—from creation to destruction. Understanding these stages gives you deeper control over how your Spring Boot applications behave internally. It allows you to initialize resources at the right time and dispose of them safely when no longer needed.
Whether you’re building REST APIs, microservices, or enterprise systems, knowing how this lifecycle works will help you write better, cleaner, and more reliable code. Now it's your turn to try lifecycle annotations in your next project.
Top comments (0)