πΉ 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)