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 registeredBeanPostProcessor
can 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
@PreDestroy
methods 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
@PostConstruct
and@PreDestroy
for most cases. - Fall back on
initMethod
/destroyMethod
for external beans. - Use
BeanPostProcessor
for advanced scenarios.
Mastering this lifecycle ensures your beans are efficient, reliable, and resource-safe throughout the lifetime of your Spring application.
Top comments (0)