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.

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".

See also