Wednesday, 11 June 2025

Spring BeanFactory lifecycle vs Spring ApplicationContext lifecycle

The BeanFactory is the most basic container in Spring, responsible for instantiating, configuring, and managing beans.

The Bean Lifecycle refers to the series of steps a bean goes through from creation to destruction within the Spring IoC (Inversion of Control) container.

Complete Lifecycle Steps in BeanFactory

  1. Bean Definition Loading

    • The container reads and parses the bean definitions (XML, annotations, or Java config).

  2. Bean Instantiation

    • The Spring container creates an instance of the bean using a constructor or a factory method.

  3. Populate Properties (Dependency Injection)

    • Spring performs dependency injection by setting properties or constructor arguments.

  4. BeanNameAware

    • If the bean implements BeanNameAware, Spring calls setBeanName(String name) passing the bean’s name.

  5. BeanFactoryAware

    • If the bean implements BeanFactoryAware, Spring calls setBeanFactory(BeanFactory beanFactory) passing the BeanFactory itself.

  6. ApplicationContextAware (if ApplicationContext used)

    • If the bean implements ApplicationContextAware, Spring injects the context via setApplicationContext().

  7. BeanPostProcessor#postProcessBeforeInitialization()

    • All registered BeanPostProcessors get a chance to modify the bean before initialization callbacks.

  8. Initialization Callbacks

    • Spring executes one or more of the following:

      • @PostConstruct annotated method

      • afterPropertiesSet() from InitializingBean interface

      • Custom init-method specified in XML or Java config

  9. BeanPostProcessor#postProcessAfterInitialization()

    • Spring again calls all BeanPostProcessors after initialization callbacks.

  10. Bean is Ready for Use

    • Now the bean is fully initialized and managed by the container.

  11. Container Shutdown Begins

  12. Destruction Callbacks

    • On container shutdown, Spring invokes:

      • @PreDestroy annotated method

      • destroy() from DisposableBean interface

      • Custom destroy-method from XML or Java config


📌 Diagram Summary

Load Bean Definition
Instantiate BeanInject DependenciesAware Interfaces (BeanNameAware, BeanFactoryAware, etc.) ↓ BeanPostProcessor - Before InitializationInit methods (@PostConstruct, afterPropertiesSet(), init-method) ↓ BeanPostProcessor - After InitializationBean Ready for UseContainer ShutdownDestroy Methods (@PreDestroy, destroy(), destroy-method)

✅ Example (with key lifecycle hooks)

@Component
public class MyBean implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean { public MyBean() { System.out.println("1. Constructor: Bean instantiated"); } @Override public void setBeanName(String name) { System.out.println("2. BeanNameAware: Bean name is " + name); } @Override public void setBeanFactory(BeanFactory beanFactory) { System.out.println("3. BeanFactoryAware: BeanFactory set"); } @PostConstruct public void postConstruct() { System.out.println("4. @PostConstruct called"); } @Override public void afterPropertiesSet() { System.out.println("5. InitializingBean: afterPropertiesSet() called"); } @PreDestroy public void preDestroy() { System.out.println("6. @PreDestroy called"); } @Override public void destroy() { System.out.println("7. DisposableBean: destroy() called"); } }

⚠️ Note:

  • BeanFactory supports all lifecycle hooks shown, but most advanced features (like @PostConstruct, @PreDestroy, ApplicationContextAware) are more commonly used with ApplicationContext, which is a superset of BeanFactory.

🌿 What is ApplicationContext?

ApplicationContext is a central interface to Spring’s advanced IoC container, building on top of BeanFactory. It not only manages beans but also provides:

  • Internationalization support

  • Event publication

  • Bean post-processing

  • Resource loading

  • Integration with Spring AOP, Environment, etc.


🔁 Lifecycle of ApplicationContext

When Spring initializes and shuts down the application context, beans go through a standard lifecycle, as described below.


Bean Lifecycle in ApplicationContext

  1. Bean Definition Parsing

    • Spring parses configuration (@Configuration, XML, annotations like @Component, etc.)

  2. Bean Instantiation

    • Beans are created using constructors or factory methods.

  3. Dependency Injection

    • Spring injects dependencies using @Autowired, constructors, setters, or fields.

  4. Aware Interfaces Called

    • If a bean implements these interfaces, Spring calls:

      • BeanNameAware: setBeanName()

      • BeanFactoryAware: setBeanFactory()

      • ApplicationContextAware: setApplicationContext()

      • EnvironmentAware, ResourceLoaderAware, etc.

  5. BeanPostProcessors – Before Initialization

    • All registered BeanPostProcessors have postProcessBeforeInitialization() called.

  6. Custom Initialization

    • Spring executes initialization callbacks:

      • @PostConstruct annotated method

      • afterPropertiesSet() from InitializingBean

      • Custom initMethod defined in @Bean(initMethod="...") or XML

  7. BeanPostProcessors – After Initialization

    • Then Spring invokes postProcessAfterInitialization() for each BeanPostProcessor.

  8. Bean Ready

    • The bean is fully initialized and available for use.

  9. Context Events (Optional)

    • ApplicationContext can publish lifecycle events like:

      • ContextRefreshedEvent

      • ContextStartedEvent

      • ContextStoppedEvent

      • ContextClosedEvent

  10. Destruction Phase (on shutdown)

  • When ApplicationContext is closed (via context.close() or application shutdown):

    • @PreDestroy is called

    • destroy() from DisposableBean

    • Custom destroyMethod from @Bean(destroyMethod="...")


📌 Lifecycle Diagram

Load Config (Java/XML/Annotations)
↓ Instantiate Beans ↓ Inject Dependencies ↓ Call Aware Interfaces ↓ BeanPostProcessor - Before Init ↓ @PostConstruct / afterPropertiesSet() / initMethod ↓ BeanPostProcessor - After Init ↓ Bean Ready ↓ (context.close() or app shutdown) ↓ @PreDestroy / destroy() / destroyMethod

✅ Sample Code: Full Bean Lifecycle

@Component
public class LifeCycleBean implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean { public LifeCycleBean() { System.out.println("1. Constructor called"); } @Override public void setBeanName(String name) { System.out.println("2. BeanNameAware: " + name); } @Override public void setApplicationContext(ApplicationContext ctx) { System.out.println("3. ApplicationContextAware: ctx available"); } @PostConstruct public void postConstruct() { System.out.println("4. @PostConstruct called"); } @Override public void afterPropertiesSet() { System.out.println("5. InitializingBean: afterPropertiesSet()"); } @PreDestroy public void preDestroy() { System.out.println("6. @PreDestroy called"); } @Override public void destroy() { System.out.println("7. DisposableBean: destroy()"); } }

💡 Key Differences from BeanFactory

FeatureBeanFactoryApplicationContext
Basic DI container
BeanPostProcessors⚠️ Manual✅ Automatic
Event handling support
Internationalization (i18n)
Annotation scanning support
Aware interfaces supportPartial
Resource loadingBasicRich

✅ Use ApplicationContext when:
  • You want full Spring features (events, environment, post-processors)

  • You're building real-world applications

  • You use @Component, @Configuration, or annotation-driven development

No comments:

Post a Comment