πΉ What is the Spring Bean Lifecycle?
π‘ Spring Beans go through multiple phases: creation, initialization, usage, and destruction.
π‘ Spring provides hooks to customize these phases (e.g., @PostConstruct, @PreDestroy).
π Phases of the Spring Bean Lifecycle
π₯ Step by Step Breakdown:
1οΈβ£ Bean Instantiation β Spring creates the bean instance.
2οΈβ£ Populate Properties (Dependency Injection) β Spring injects dependencies.
3οΈβ£ Bean Name is Set (BeanNameAware#setBeanName())
4οΈβ£ Bean Factory is Set (BeanFactoryAware#setBeanFactory())
5οΈβ£ ApplicationContext is Set (ApplicationContextAware#setApplicationContext())
6οΈβ£ Before Initialization Processing (BeanPostProcessor#postProcessBeforeInitialization())
7οΈβ£ Custom Initialization Methods:
InitializingBean#afterPropertiesSet()@PostConstruct-
init-method(if specified in XML or@Bean)
8οΈβ£ After Initialization Processing (BeanPostProcessor#postProcessAfterInitialization())
9οΈβ£ Bean is Ready for Use! π
π Before Destruction Processing (DestructionAwareBeanPostProcessor#postProcessBeforeDestruction())
1οΈβ£1οΈβ£ Custom Destruction Methods:
DisposableBean#destroy()@PreDestroy-
destroy-method(if specified in XML or@Bean)
1οΈβ£2οΈβ£ Bean is Removed (Garbage Collected).
π₯ This entire process is controlled by Springβs ApplicationContext!
π Hands-On Project: Bean Lifecycle in Action
π‘ Letβs create a small Spring Boot app to observe and control the Bean Lifecycle.
Step 1: Create a Spring Boot Project
1οΈβ£ Go to Spring Initializr
2οΈβ£ Select:
- Spring Boot Version: Latest stable
- Dependencies: Spring Web
- Packaging: Jar 3οΈβ£ Click Generate and extract the zip file.
Step 2: Define a Bean with Lifecycle Hooks
π Create a Pirate Bean with Lifecycle Annotations:
package com.example.lifecycle; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import org.springframework.stereotype.Component; @Component public class Pirate { public Pirate() { System.out.println("β Pirate Bean Instantiated!"); } @PostConstruct public void prepareForSailing() { System.out.println("π΄ββ οΈ @PostConstruct: Pirate is ready for adventure!"); } @PreDestroy public void retireFromSailing() { System.out.println("β οΈ @PreDestroy: Pirate is retiring..."); } } π‘ What happens here?
β
Pirate() β Constructor is called (bean instantiation).
β
@PostConstruct β Called after dependencies are injected but before the bean is used.
β
@PreDestroy β Called before the bean is destroyed (removed from context).
Step 3: Add BeanPostProcessor to Track Lifecycle Events
π Create a PirateLifecycleLogger to observe Springβs lifecycle hooks:
package com.example.lifecycle; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.stereotype.Component; @Component public class PirateLifecycleLogger implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { System.out.println("β³ Before Initialization: " + beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) { System.out.println("β
After Initialization: " + beanName); return bean; } } π‘ What happens here?
β
postProcessBeforeInitialization() runs before @PostConstruct and afterPropertiesSet().
β
postProcessAfterInitialization() runs after initialization but before usage.
Step 4: Create the Main Application Class
π Modify SpringBootApplication to trigger the lifecycle:
package com.example.lifecycle; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class LifecycleApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(LifecycleApplication.class, args); System.out.println("π³οΈ Application is Running..."); // Close context to trigger @PreDestroy context.close(); } } π‘ Why context.close()?
β
It manually shuts down the Spring application, triggering @PreDestroy!
Step 5: Run the Application
π‘ Run the app using:
mvn spring-boot:run or
./mvnw spring-boot:run π Expected Output:
β Pirate Bean Instantiated! β³ Before Initialization: pirate π΄ββ οΈ @PostConstruct: Pirate is ready for adventure! β
After Initialization: pirate π³οΈ Application is Running... β οΈ @PreDestroy: Pirate is retiring... π₯ Boom! You just witnessed the Spring Bean Lifecycle in action!
π Summary of Step 3
β
Spring Beans have a lifecycle controlled by ApplicationContext.
β
Spring calls lifecycle methods like @PostConstruct and @PreDestroy.
β
BeanPostProcessor allows custom pre/post-initialization logic.
β
context.close() manually triggers destruction lifecycle.
π Topics Covered in This Section
π Spring Bean Lifecycle (βοΈ Covered)
How Beans are created & destroyed (Instantiation β Initialization β Destruction).
-
Lifecycle methods:
- @PostConstruct (Runs after properties are set).
- @PreDestroy (Runs before bean destruction).
-
BeanPostProcessor Hooks:
- postProcessBeforeInitialization()
- postProcessAfterInitialization()
Manually closing the ApplicationContext (context.close()).
π₯ Key Takeaways to Remember:
β
Spring manages bean lifecycles automatically using ApplicationContext.
β
@PostConstruct and @PreDestroy are commonly used for lifecycle management.
β
BeanPostProcessor allows customization before/after initialization.
β
Manually closing the ApplicationContext triggers @PreDestroy.
Top comments (0)