Cả ba đều chạy, theo đúng thứ tự:
1. Method gắn @PostConstruct
2. InitializingBean.afterPropertiesSet()
3. init-method khai báo trong @Bean(initMethod = "...")
Khi hủy bean, thứ tự tương ứng là @PreDestroy → DisposableBean.destroy() → destroyMethod. Nếu cả ba cơ chế cùng trỏ vào một tên method, method đó chỉ chạy một lần.
Đặt trong bức tranh lớn hơn của quá trình khởi tạo bean:
instantiate -> populate properties (DI)
-> *Aware callbacks (BeanNameAware, BeanFactoryAware, ApplicationContextAware...)
-> BeanPostProcessor.postProcessBeforeInitialization
-> @PostConstruct -> afterPropertiesSet() -> initMethod
-> BeanPostProcessor.postProcessAfterInitialization // AOP proxy is created here
-> bean readyHai điểm hay bị hỏi tiếp:
- Proxy AOP được tạo ở bước postProcessAfterInitialization, tức là sau các callback khởi tạo. Vì vậy gọi một method có @Transactional/@Async của chính bean đó ngay trong @PostConstruct sẽ không đi qua proxy và không có hiệu lực.
- Với bean scope prototype, các callback khởi tạo vẫn chạy nhưng callback hủy không bao giờ được gọi — container không giữ tham chiếu tới instance đó.
Thực tế nên chọn một cơ chế: @PostConstruct cho bean của mình, initMethod cho class bên thứ ba không sửa được.