DEV Community

Hunor Vadasz-Perhat
Hunor Vadasz-Perhat

Posted on

spring-011: spring-bean-lifecycle-execution-order

Here is the complete logical execution order of the Spring Bean Lifecycle, integrating all relevant lifecycle interfaces of the BeanFactory interface along with methods, ensuring a full picture of the flow.


🔷 1. Logical Execution Order of Spring Bean Lifecycle

(From Instantiation to Destruction)

1️⃣ Bean Definition is Loaded (Metadata Processing)

  • Spring reads bean definitions from configuration files (@Configuration), XML files, or component scanning (@Component).
  • This is a metadata processing step—no instances are created yet.
  • 💡 Related method: BeanDefinitionRegistry#registerBeanDefinition()

2️⃣ Bean Instantiation (Object Creation)

  • The actual bean object is created either via:
    • Constructor instantiation
    • Factory method
  • 💡 Related method: InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()

3️⃣ Set Bean Name (BeanNameAware#setBeanName(String name))

  • If the bean implements BeanNameAware, Spring calls setBeanName() to inform the bean of its own name.
  • This happens before dependencies are injected.
  • 💡 Use Case: If a bean needs to know its name in the application context.
   public class MyBean implements BeanNameAware {
       @Override
       public void setBeanName(String name) {
           System.out.println("Bean Name Set: " + name);
       }
   }
Enter fullscreen mode Exit fullscreen mode

4️⃣ Set Bean ClassLoader (BeanClassLoaderAware#setBeanClassLoader(ClassLoader classLoader))

  • Spring calls this method if the bean needs access to its ClassLoader.
  • 💡 Use Case: Useful if a bean dynamically loads classes at runtime.
   public class MyBean implements BeanClassLoaderAware {
       @Override
       public void setBeanClassLoader(ClassLoader classLoader) {
           System.out.println("ClassLoader Set!");
       }
   }
Enter fullscreen mode Exit fullscreen mode

5️⃣ Set BeanFactory (BeanFactoryAware#setBeanFactory(BeanFactory factory))

  • Spring injects the BeanFactory into the bean.
  • 💡 Use Case: Allows the bean to get other beans programmatically.
   public class MyBean implements BeanFactoryAware {
       @Override
       public void setBeanFactory(BeanFactory beanFactory) {
           System.out.println("BeanFactory Set!");
       }
   }
Enter fullscreen mode Exit fullscreen mode

6️⃣ Set Environment (EnvironmentAware#setEnvironment(Environment environment))

  • If the bean needs access to environment variables and properties, this method is called.
  • 💡 Use Case: Useful for accessing application.properties values dynamically.
   public class MyBean implements EnvironmentAware {
       @Override
       public void setEnvironment(Environment environment) {
           System.out.println("Environment Set!");
       }
   }
Enter fullscreen mode Exit fullscreen mode

7️⃣ Set Embedded Value Resolver (EmbeddedValueResolverAware#setEmbeddedValueResolver(StringValueResolver resolver))

  • Allows the bean to resolve placeholders (${property}) programmatically.
  • 💡 Use Case: Useful when a bean needs to manually resolve placeholders.
   public class MyBean implements EmbeddedValueResolverAware {
       @Override
       public void setEmbeddedValueResolver(StringValueResolver resolver) {
           System.out.println("Value Resolver Set!");
       }
   }
Enter fullscreen mode Exit fullscreen mode

8️⃣ Set ResourceLoader (ResourceLoaderAware#setResourceLoader(ResourceLoader loader))

  • Only applicable in ApplicationContext, used to load resources dynamically.
  • 💡 Use Case: Load files, classpath resources, or external resources.

9️⃣ Set Application Event Publisher (ApplicationEventPublisherAware#setApplicationEventPublisher(ApplicationEventPublisher publisher))

  • If a bean needs to publish events, this method is called.
  • 💡 Use Case: Used to broadcast events like ContextRefreshedEvent.

🔟 Set Message Source (MessageSourceAware#setMessageSource(MessageSource source))

  • If the bean needs internationalization (i18n) support, Spring injects the MessageSource.

1️⃣1️⃣ Set ApplicationContext (ApplicationContextAware#setApplicationContext(ApplicationContext ctx))

  • If a bean needs access to the entire Spring ApplicationContext, this method is called.
  • 💡 Use Case: Allows dynamic access to other beans, environment settings, etc.

1️⃣2️⃣ Set ServletContext (ServletContextAware#setServletContext(ServletContext ctx))

  • Only applicable for web applications, used to access web context information.

1️⃣3️⃣ Post-Processing Before Initialization (BeanPostProcessor#postProcessBeforeInitialization())

  • Allows modification of the bean before it is initialized.

1️⃣4️⃣ Custom Initialization

  • InitializingBean’s afterPropertiesSet()
  • Custom @PostConstruct method
  • Custom init-method in @Bean
   @PostConstruct
   public void init() {
       System.out.println("PostConstruct Method Called!");
   }
Enter fullscreen mode Exit fullscreen mode

1️⃣5️⃣ Post-Processing After Initialization (BeanPostProcessor#postProcessAfterInitialization())

  • Allows modification of the bean after initialization.
  • 💡 Use Case: Used for creating proxies, logging, or aspect-oriented programming (AOP).

1️⃣6️⃣ Bean is Ready for Use

  • The bean is fully initialized and ready to be used in the application.

🔷 2. Destruction Phase (Bean Shutdown Lifecycle)

When the application shuts down, Spring destroys the beans gracefully.

1️⃣ Pre-Destruction Processing (DestructionAwareBeanPostProcessor#postProcessBeforeDestruction())

  • Allows cleanup before destruction.

2️⃣ DisposableBean’s destroy() Method

  • If the bean implements DisposableBean, destroy() is called.
   public class MyBean implements DisposableBean {
       @Override
       public void destroy() {
           System.out.println("DisposableBean Destroy Called!");
       }
   }
Enter fullscreen mode Exit fullscreen mode

3️⃣ Custom @PreDestroy Method (Preferred Approach)

  • More modern than DisposableBean, called before the bean is destroyed.
   @PreDestroy
   public void cleanup() {
       System.out.println("PreDestroy Called!");
   }
Enter fullscreen mode Exit fullscreen mode

4️⃣ Custom destroy-method (If Defined in @Bean)

  • Alternative approach for defining cleanup logic.

🔷 3. Complete Flow Summary (Final Order)

🟢 Bean Initialization Phase

1️⃣ Load Bean Definitions

2️⃣ Instantiate Bean (new Bean())

3️⃣ setBeanName() (BeanNameAware)

4️⃣ setBeanClassLoader() (BeanClassLoaderAware)

5️⃣ setBeanFactory() (BeanFactoryAware)

6️⃣ setEnvironment() (EnvironmentAware)

7️⃣ setEmbeddedValueResolver() (EmbeddedValueResolverAware)

8️⃣ setResourceLoader() (ResourceLoaderAware)

9️⃣ setApplicationEventPublisher() (ApplicationEventPublisherAware)

🔟 setMessageSource() (MessageSourceAware)

1️⃣1️⃣ setApplicationContext() (ApplicationContextAware)

1️⃣2️⃣ setServletContext() (ServletContextAware)

1️⃣3️⃣ postProcessBeforeInitialization() (BeanPostProcessor)

1️⃣4️⃣ @PostConstruct / afterPropertiesSet()

1️⃣5️⃣ postProcessAfterInitialization() (BeanPostProcessor)

1️⃣6️⃣ Bean is Ready for Use


🔴 Bean Destruction Phase

1️⃣ postProcessBeforeDestruction() (DestructionAwareBeanPostProcessor)

2️⃣ destroy() (DisposableBean)

3️⃣ @PreDestroy

4️⃣ destroy-method


More info on BeanFactory interface and its methods here: https://docs.spring.io/spring-framework/docs/6.2.2/javadoc-api/org/springframework/beans/factory/BeanFactory.html

Happy Coding 🚀

Top comments (0)