Events

Events let one bean announce that something happened, and let any number of other beans react to it.

Why use it

Without events, the order service would call the mailer, the stock service and the analytics itself. Every new reaction means editing the order service. With events, the order service only publishes "order placed". The mailer, the stock and the analytics listen. Neither side knows the other.

Use events for reactions that are not part of the main job of the publisher. Do not use them when the caller needs an answer: call the other bean directly.

The context also publishes events about itself, such as ContextRefreshedEvent once every bean is ready.

Example

import 'package:spring_core_dart/spring_core_dart.dart';

// Any object can be an event; it does not need a base class.
class OrderPlaced {
  const OrderPlaced(this.id, this.total);
  final String id;
  final double total;
}

@Service()
class Orders {
  Orders(this.events);

  // The context itself is injected as the publisher.
  final ApplicationEventPublisher events;

  void place(String id, double total) =>
      events.publishEvent(OrderPlaced(id, total));
}

@Component()
@Log()
class Analytics {
  // Called for every published OrderPlaced.
  @EventListener()
  void onPlaced(OrderPlaced order) => log.info('order ${order.id}');
}

By default listeners run inside publishEvent, so the publisher waits for them. @Async changes that for one listener.

Pages

In Spring (Java)

@Service
class Orders {
  private final ApplicationEventPublisher events;
  Orders(ApplicationEventPublisher events) { this.events = events; }

  void place(String id, double total) {
    events.publishEvent(new OrderPlaced(id, total));
  }
}

@Component
class Analytics {
  @EventListener
  void onPlaced(OrderPlaced order) { ... }
}

The model is the same. The main differences: a listener condition is a Dart function instead of a SpEL string, and @Async works only on @EventListener methods.

See also