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
ContextClosedEvent
for 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
@PostConstruct
for bean-level setup. - Use
ApplicationReadyEvent
or 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)