Spring instantiates the bean (constructor), populates properties and @Autowired dependencies, fires *Aware callbacks, then BeanPostProcessor.postProcessBeforeInitialization, then init callbacks (@PostConstruct, then InitializingBean.afterPropertiesSet, then a custom init-method), then BeanPostProcessor.postProcessAfterInitialization. AOP proxies for @Transactional, @Async, and @Cacheable are created in that final after-initialization step, which is exactly why a self-call bypasses them. On shutdown the container runs @PreDestroy, DisposableBean.destroy, then any destroy-method, in reverse creation order.
- Forgetting where BeanPostProcessors and AOP proxies are created.
- Saying @PreDestroy runs for prototype beans.