Spring Boot applications go through a well-defined lifecycle, which can be divided into bean-level, application-level, and shutdown phases. Knowing this lifecycle is essential for initialization tasks, resource management, and graceful shutdown in production-grade microservices.
1οΈβ£ Application Startup Phases
When a Spring Boot application starts:
- SpringApplication bootstrap
- Loads
ApplicationContext. - Registers beans, configurations, and property sources.
- Bean instantiation & dependency injection
- Spring creates all singleton beans.
- Dependencies are injected (constructor, field, or setter injection).
a. Bean-Level Hooks
| Hook | When it Runs | Use Case |
|---|---|---|
@PostConstruct |
After bean is created & dependencies injected | Lightweight initialization |
InitializingBean.afterPropertiesSet() |
After properties are set | Programmatic alternative to @PostConstruct
|
@Bean(initMethod="...") |
After bean creation (Java config) | Legacy or custom init method |
Example:
@Component
public class MyBean {
@PostConstruct
public void init() {
System.out.println("Bean initialized");
}
}
b. Application-Level Hooks
| Hook | When it Runs | Notes |
|---|---|---|
CommandLineRunner |
After Spring context is ready | Receives raw String[] args
|
ApplicationRunner |
After Spring context is ready | Receives parsed ApplicationArguments
|
ApplicationReadyEvent |
After the app is fully started and server ready | Ideal for warm-up tasks or metrics |
Example with ApplicationReadyEvent:
@Component
public class AppReadyListener {
@EventListener(ApplicationReadyEvent.class)
public void onReady() {
System.out.println("Application is fully started and ready to serve requests");
}
}
c. SmartLifecycle Interface
- Used for complex beans that require start/stop order.
- Provides
start(),stop(),isRunning(),getPhase()methods.
@Component
public class MyLifecycleBean implements SmartLifecycle {
@Override
public void start() { System.out.println("Starting bean"); }
@Override
public void stop() { System.out.println("Stopping bean"); }
@Override
public boolean isRunning() { return true; }
@Override
public int getPhase() { return 0; }
@Override
public boolean isAutoStartup() { return true; }
}
2οΈβ£ Application Running
Once started:
- Embedded web server (Tomcat/Jetty/Netty) is up.
- Beans are ready to serve requests.
- Tasks like cache warm-up or external service validation can safely run.
3οΈβ£ Application Shutdown
Spring Boot supports graceful shutdown, giving a chance to clean up resources:
a. Bean-Level Shutdown Hooks
| Hook | When it Runs | Example |
|---|---|---|
@PreDestroy |
Before bean destruction | Close DB connections, release resources |
DisposableBean.destroy() |
Programmatic cleanup alternative | Same as @PreDestroy
|
@Component
public class CleanupBean {
@PreDestroy
public void cleanup() {
System.out.println("Cleaning up resources before shutdown");
}
}
b. Application Context Close Event
- Listen to
ContextClosedEventfor global cleanup:
@Component
public class ShutdownListener {
@EventListener(ContextClosedEvent.class)
public void onShutdown() {
System.out.println("Application context is closing");
}
}
4οΈβ£ Summary Timeline
SpringApplication.run()
β
βΌ
ApplicationContext initialized
β
βΌ
Bean instantiation & dependency injection
β
@PostConstruct / InitializingBean / init-method
β
βΌ
CommandLineRunner / ApplicationRunner
β
βΌ
ApplicationReadyEvent
β
βΌ
Application running (serving requests)
β
Shutdown initiated
β
@PreDestroy / DisposableBean / ContextClosedEvent
β
βΌ
Application stops
5οΈβ£ Best Practices
- Separate lightweight vs heavy tasks
- Use
@PostConstructfor bean-level setup. - Use
ApplicationReadyEventor runners for heavy, app-wide initialization.
- Make startup tasks idempotent
- Especially important for Kubernetes pods that may restart.
- Graceful shutdown
- Always release resources and deregister services in shutdown hooks.
- Integrate with observability
- Log startup/shutdown events, expose metrics, and integrate with readiness/liveness probes if running in Kubernetes.
This lifecycle understanding is crucial for microservices architecture, especially when combining Spring Boot hooks with Kubernetes pod lifecycle hooks like postStart and preStop.
Top comments (0)