Swiftorial Logo
Home
Swift Lessons
AI Tools
Learn More
Career
Resources

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 XML init-method/destroy-method.

πŸ”Ž Extended Lifecycle Order (what actually happens):

  1. Instantiate β€” container creates the bean (constructor or factory method).
  2. Populate Properties β€” dependency injection (constructor/setter/field).
  3. Aware Interfaces (optional) β€” if implemented:
    • BeanNameAware.setBeanName()
    • BeanFactoryAware.setBeanFactory()
    • ApplicationContextAware.setApplicationContext()
  4. BeanPostProcessor: before init β€” postProcessBeforeInitialization() for all processors.
  5. Initialization callbacks (any/all that apply, in this general order):
    • @PostConstruct
    • afterPropertiesSet() (from InitializingBean)
    • custom initMethod
  6. BeanPostProcessor: after init β€” postProcessAfterInitialization().
  7. Ready for Use β€” bean participates in your app logic.
  8. Destruction callbacks (on context shutdown):
    • @PreDestroy
    • destroy() (from DisposableBean)
    • 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/@PreDestroy for concise, framework-agnostic code (JSR-250).
  • Use InitializingBean/DisposableBean when you need explicit Spring interfaces.
  • For third-party classes you can’t modify, set @Bean(initMethod="…", destroyMethod="…") in a @Configuration class.

πŸ“Œ Notes, Tips & Pitfalls:

  • Order of init callbacks: @PostConstruct β†’ afterPropertiesSet() β†’ custom initMethod.
  • 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 BeanPostProcessor proxies/wraps the bean, your postProcessAfterInitialization() 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 @PreDestroy will 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]
        
← Back to Q&A