Context events
Context events are the events an application context publishes about its own life: refreshed, started, stopped, paused, restarted and closed.
Why use it
Some work must happen at a moment of the context's life, not when one bean is created.
- Warm a cache or log a "ready" line once every bean exists:
ContextRefreshedEvent. - Save state while every bean still works, before shutdown:
ContextClosedEvent. - React when background work is paused or resumed, for example while a Flutter app is in the background:
ContextPausedEvent,ContextRestartedEvent.
Applications receive these events; they never create them. Listen with an @EventListener method, an ApplicationListener, or context.addListener. For setup of one bean, @PostConstruct is simpler.
Example
import 'package:spring_core_dart/spring_core_dart.dart';
abstract interface class SessionRepository {
void saveAll();
}
@Component()
@Log()
class Lifecycle {
Lifecycle(this.sessions);
final SessionRepository sessions;
// Every eager singleton exists and the auto-startup beans run.
@EventListener()
void onReady(ContextRefreshedEvent event) =>
log.info('ready: ${event.applicationContext.id}');
// The first step of close(): other beans can still be used here.
@EventListener()
void onClose(ContextClosedEvent event) => sessions.saveAll();
}
The base class ApplicationContextEvent receives all of them:
@Component()
@Log()
class ContextLog {
@EventListener()
void on(ApplicationContextEvent event) =>
log.info('${event.runtimeType} of ${event.applicationContext.id}');
}
Members
| Event | Published when | Notes |
|---|---|---|
ApplicationContextEvent |
(base class) | applicationContext is the context that raised the event, the same object as source. |
ContextRefreshedEvent |
The last step of refresh(): every eager singleton exists and the auto-startup lifecycle beans run. |
If a listener throws, the refresh fails (unless the multicaster has an error handler). |
ContextStartedEvent |
After an explicit start(), typically after stop(). |
Not published during the first startup. |
ContextStoppedEvent |
After stop(): running lifecycle beans are stopped. |
The beans still exist. close() does not publish it. |
ContextRestartedEvent |
After restart(): the auto-startup lifecycle beans run again. |
A subclass of ContextStartedEvent. New in Spring 7. |
ContextPausedEvent |
After pause() or pauseAsync(): pauseable lifecycle beans are stopped. |
A subclass of ContextStoppedEvent. New in Spring 7. |
ContextClosedEvent |
The first step of close(), while every bean is still available. |
A listener error is logged and the shutdown goes on. |
Events published in a child context reach the parent's listeners too. Compare applicationContext when that matters.
In Spring (Java)
@Component
class Lifecycle {
@EventListener
void onReady(ContextRefreshedEvent event) { ... }
@EventListener
void onClose(ContextClosedEvent event) { sessions.saveAll(); }
}
The events and their order are the same as in Spring 7. With Spring Boot (spring_boot_dart), ApplicationReadyEvent comes after the runners and is usually a better moment than ContextRefreshedEvent for "the application is ready".