What Is the Spring Bean Lifecycle?
Every Spring Bean goes through a defined lifecycle managed by the ApplicationContext. Understanding this lifecycle is essential for the VMware Spring Professional exam (2V0-72.22) and for writing robust production code.
The lifecycle has 5 key phases:
- Instantiation — the bean object is created
- Dependency Injection — properties and dependencies are set
- Initialization — custom init logic runs
- Bean is Ready — the bean serves requests
- Destruction — cleanup logic runs on context shutdown
Phase 1: Instantiation
Spring creates a bean instance using:
- The default no-arg constructor (most common)
- A factory method (via
@Beanin@Configuration) - A static factory method
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService(); // Spring calls this factory method
}
}
For @Component-annotated classes, Spring calls the constructor directly:
@Component
public class OrderService {
// Spring calls this no-arg constructor
public OrderService() {}
}
Phase 2: Dependency Injection
After instantiation, Spring populates the bean's dependencies via:
- Constructor injection (preferred)
- Setter injection
- Field injection (
@Autowiredon field — not recommended)
@Component
public class OrderService {
private final PaymentService paymentService;
// Constructor injection — recommended
@Autowired // optional since Spring 4.3 if single constructor
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
Phase 3: Initialization Callbacks
After dependency injection is complete, Spring calls initialization callbacks in this exact order:
1. @PostConstruct (recommended)
@Component
public class CacheService {
@PostConstruct
public void init() {
// Runs after DI is complete
System.out.println("Cache warming up...");
}
}
2. InitializingBean.afterPropertiesSet()
@Component
public class CacheService implements InitializingBean {
@Override
public void afterPropertiesSet() {
// Called by Spring after properties are set
}
}
3. Custom init-method
@Bean(initMethod = "setup")
public CacheService cacheService() {
return new CacheService();
}
Exam tip: The order is always:
@PostConstruct→afterPropertiesSet()→ custominit-method.
Phase 4: Bean Is Ready
The bean is now fully initialized and stored in the ApplicationContext. All subsequent getBean() calls return the same singleton instance (with default scope).
Phase 5: Destruction Callbacks
When the ApplicationContext is closed, Spring calls destruction callbacks in this order:
1. @PreDestroy (recommended)
@Component
public class CacheService {
@PreDestroy
public void cleanup() {
// Runs before the bean is destroyed
System.out.println("Clearing cache...");
}
}
2. DisposableBean.destroy()
@Component
public class CacheService implements DisposableBean {
@Override
public void destroy() {
// Called by Spring on context shutdown
}
}
3. Custom destroy-method
@Bean(destroyMethod = "shutdown")
public CacheService cacheService() {
return new CacheService();
}
Exam Quick Reference
| Callback | Order | Interface/Annotation |
|---|---|---|
| Init 1 | 1st | @PostConstruct |
| Init 2 | 2nd | InitializingBean.afterPropertiesSet() |
| Init 3 | 3rd | Custom init-method |
| Destroy 1 | 1st | @PreDestroy |
| Destroy 2 | 2nd | DisposableBean.destroy() |
| Destroy 3 | 3rd | Custom destroy-method |
Common Exam Questions
Q: Which initialization callback runs first — @PostConstruct or afterPropertiesSet()?
@PostConstruct runs first. The order is @PostConstruct → afterPropertiesSet() → custom init-method.
Q: Do destruction callbacks run for prototype-scoped beans?
No. Spring does not manage the full lifecycle of prototype beans. After returning a prototype instance, Spring does not call destroy callbacks on it.
Q: What triggers the destruction phase?
Calling context.close() or registering a JVM shutdown hook via context.registerShutdownHook().