Spring Framework FAQ: Top Questions
9. What are Spring Bean lifecycle methods?
Spring beans move through a well-defined lifecycle managed by the IoC container: creation, dependency injection, initialization, usage, and destruction. You can hook into these stages to prepare resources (e.g., open DB connections, warm caches) and clean them up (e.g., close pools, stop schedulers).
π Key Methods:
@PostConstructβ run after dependency injection but before the bean is used.InitializingBean.afterPropertiesSet()β interface-based init callback.@PreDestroyβ run right before container destroys the bean.DisposableBean.destroy()β interface-based destroy callback.- Custom
@Bean(initMethod="β¦", destroyMethod="β¦")or XMLinit-method/destroy-method.
π Extended Lifecycle Order (what actually happens):
- Instantiate β container creates the bean (constructor or factory method).
- Populate Properties β dependency injection (constructor/setter/field).
- Aware Interfaces (optional) β if implemented:
BeanNameAware.setBeanName()BeanFactoryAware.setBeanFactory()ApplicationContextAware.setApplicationContext()
- BeanPostProcessor: before init β
postProcessBeforeInitialization()for all processors. - Initialization callbacks (any/all that apply, in this general order):
@PostConstructafterPropertiesSet()(fromInitializingBean)- custom
initMethod
- BeanPostProcessor: after init β
postProcessAfterInitialization(). - Ready for Use β bean participates in your app logic.
- Destruction callbacks (on context shutdown):
@PreDestroydestroy()(fromDisposableBean)- custom
destroyMethod
π₯ Example:
@Component
public class MyService {
@PostConstruct
public void init() {
System.out.println("Bean is initialized");
// e.g., warm up caches, start a scheduler, validate configuration
}
@PreDestroy
public void cleanup() {
System.out.println("Bean is about to be destroyed");
// e.g., flush metrics, stop scheduler, close resources
}
}
π Expected Output:
Bean is initialized
... (application runs) ...
Bean is about to be destroyed
π οΈ Use Cases:
- Resource setup (DB pools, HTTP clients, caches, message consumers).
- Graceful cleanup (closing sockets, stopping threads/executors, persisting state).
- Validating configuration and precomputing expensive data at startup.
βοΈ Annotations vs Interfaces vs Config Methods:
- Prefer
@PostConstruct/@PreDestroyfor concise, framework-agnostic code (JSR-250). - Use
InitializingBean/DisposableBeanwhen you need explicit Spring interfaces. - For third-party classes you canβt modify, set
@Bean(initMethod="β¦", destroyMethod="β¦")in a@Configurationclass.
π Notes, Tips & Pitfalls:
- Order of init callbacks:
@PostConstructβafterPropertiesSet()β custominitMethod. - Singleton vs Prototype: destruction callbacks are invoked automatically for singletons. For prototype beans, the container does not call destroy methodsβmanage cleanup yourself.
- Conditional creation: if a
BeanPostProcessorproxies/wraps the bean, yourpostProcessAfterInitialization()runs on the proxy. - Async resources: make sure background threads or schedulers are shut down in
@PreDestroy. - Testing: with
@SpringBootTest, the context closes after tests, so@PreDestroywill runβavoid long-running cleanup.
π Lifecycle Flow:
graph TD
A[Bean Instantiation] --> B[Populate Properties / Dependency Injection]
B --> C[Aware Interfaces: setBeanName/Factory/Context]
C --> D[BeanPostProcessor: postProcessBeforeInitialization()]
D --> E[@PostConstruct β afterPropertiesSet() β initMethod]
E --> F[BeanPostProcessor: postProcessAfterInitialization()]
F --> G[Bean Ready for Use]
G --> H[@PreDestroy β destroy() β destroyMethod]
