
# 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

```dart
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

- [@EventListener](event-listener.md): a bean method that is called for each event of its parameter type, with conditions and order.
- [@Async](async.md): run a listener on a `TaskExecutor`, so the publisher does not wait.
- [ApplicationEvent](application-event.md): the event base class, the publisher, and the listener interfaces.
- [Context events](context-events.md): the events the context publishes about itself (refreshed, started, stopped, closed, ...).

## In Spring (Java)

```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

- [Beans](../beans/index.md)
- [ApplicationContext](../beans/application-context.md)
- [Logging](../logging/index.md)
