The bean lifecycle is a fixed, ordered chain, and knowing the exact sequence — especially that BeanPostProcessor brackets the init callbacks — is the heart of this question. The container drives every step; your code only plugs into the hooks.
Creation order (instantiation to ready)
- Instantiate — Spring calls the constructor (or factory method). Constructor injection happens here.
- Populate properties — field/setter dependency injection runs;
@Autowiredfields and setters are filled. Awarecallbacks — in order:BeanNameAware.setBeanName,BeanFactoryAware.setBeanFactory, thenApplicationContextAware.setApplicationContext.BeanPostProcessor.postProcessBeforeInitialization— every registered BPP gets a crack at the instance before init callbacks. (This is where@PostConstructis actually triggered, viaCommonAnnotationBeanPostProcessor.)@PostConstruct— your annotated init method.InitializingBean.afterPropertiesSet()— if the bean implements it.- Custom
init-method— declared via@Bean(initMethod=...)or XML. BeanPostProcessor.postProcessAfterInitialization— runs after init. AOP proxies (e.g.@Transactional) are created here, so the object handed out can be a proxy wrapping your bean.- Ready — the bean is fully initialized and cached (for singletons).
@Component
public class Engine implements InitializingBean {
@PostConstruct void warmUp() { } // step 5
public void afterPropertiesSet() { } // step 6 — runs after warmUp()
}
Destruction order (reverse-ish)
On context shutdown, for singletons only:
@PreDestroy— your annotated cleanup method.DisposableBean.destroy().- Custom
destroy-method.
START -> @PostConstruct -> afterPropertiesSet() -> initMethod
SHUTDOWN -> @PreDestroy -> destroy() -> destroyMethod