In the Spring Framework, beans are the backbone of any application. They represent the objects that Spring manages inside its IoC (Inversion of Control) container.
To truly harness Springβs power, itβs important to understand how beans are created, initialized, and destroyed β in other words, their lifecycle.
π The Bean Lifecycle in Spring
When you declare a bean using annotations (@Component) or configuration (@Bean), Spring takes full control over it.
Hereβs the typical lifecycle flow:
Bean Instantiation
Spring creates the bean instance (via constructor or factory method).Dependency Injection
Required dependencies are injected into the beanβs fields, setters, or constructors.Aware Interfaces (Optional)
If your bean implements aware interfaces, Spring provides additional context:
-
BeanNameAwareβ gives the beanβs name. -
BeanFactoryAwareβ gives access to the bean factory. -
ApplicationContextAwareβ gives access to the application context.
BeanPostProcessor β Before Initialization
Any registeredBeanPostProcessorcan manipulate the bean before initialization.Initialization Phase
- If the bean implements
InitializingBean, theafterPropertiesSet()method is called. - If the bean defines an init method, Spring calls it.
- If annotated with
@PostConstruct, that method executes here.
BeanPostProcessor β After Initialization
Beans may be wrapped or enhanced after initialization (e.g., proxy creation for AOP).Bean Ready for Use
At this stage, the bean is fully initialized and can be used within the application.Destruction Phase
When the application context is closed:
- If the bean implements
DisposableBean, thedestroy()method runs. - Any
@PreDestroymethods or custom destroy methods are executed.
β Lifecycle Hook Options
Spring provides multiple ways to plug into this lifecycle.
1. Using @PostConstruct and @PreDestroy (Modern & Recommended)
@Component
public class MyBean {
@PostConstruct
public void init() {
System.out.println("Bean initialized: resources opened");
}
@PreDestroy
public void cleanup() {
System.out.println("Bean destroyed: resources released");
}
}
2. Using InitializingBean and DisposableBean
@Component
public class MyBean implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() {
System.out.println("afterPropertiesSet() called");
}
@Override
public void destroy() {
System.out.println("destroy() called");
}
}
3. Specifying Init and Destroy Methods in @Bean
@Configuration
public class AppConfig {
@Bean(initMethod = "customInit", destroyMethod = "customDestroy")
public MyBean myBean() {
return new MyBean();
}
}
public class MyBean {
public void customInit() {
System.out.println("Custom init method");
}
public void customDestroy() {
System.out.println("Custom destroy method");
}
}
4. Using BeanPostProcessor (For Cross-Cutting Concerns)
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
System.out.println("Before init: " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
System.out.println("After init: " + beanName);
return bean;
}
}
π Visualizing the Lifecycle
[Instantiation]
β
[Dependency Injection]
β
[Aware Interfaces]
β
[BeanPostProcessor (Before Init)]
β
[Init Phase β @PostConstruct / afterPropertiesSet() / initMethod()]
β
[BeanPostProcessor (After Init)]
β
[Bean Ready for Use]
β
[Destruction β @PreDestroy / destroy() / destroyMethod()]
π Quick Comparison of Methods
| Approach | When to Use |
|---|---|
@PostConstruct / @PreDestroy
|
β Recommended in modern Spring apps |
InitializingBean / DisposableBean
|
Useful when you want to bind directly to interfaces |
initMethod / destroyMethod in @Bean
|
Useful when you donβt control the bean class (e.g., third-party beans) |
BeanPostProcessor |
For cross-cutting concerns (logging, proxying, monitoring) |
π Conclusion
The Spring Bean Lifecycle gives you multiple hooks to manage resources, initialize connections, and perform cleanup.
- Use
@PostConstructand@PreDestroyfor most cases. - Fall back on
initMethod/destroyMethodfor external beans. - Use
BeanPostProcessorfor advanced scenarios.
Mastering this lifecycle ensures your beans are efficient, reliable, and resource-safe throughout the lifetime of your Spring application.
Top comments (0)