Events
Modules in an Across application often use events to communicate with each other. To this end, Across fully supports the Spring framework event listening features.
This chapter lists the most common event features, please refer to the Spring framework documentation for all details.
Subscribing to events
The most common way to subscribe to an event is by simply providing an @EventListener
annotated method.
A single object can have many listener methods.
All beans created in the ApplicationContext
are automatically scanned for event listener methods.
@Component
public class MyHandler {
@EventListener
public void handle( SomeEvent event ) {
// Called whenever an event of type SomeEvent is published
}
}
Publishing events
Publishing events is done via the ApplicationEventPublisher
bean.
@Autowired
private ApplicationEventPublisher eventPublisher;
public void sendEvent() {
eventPublisher.publishEvent( new SomeEvent() );
}
Filtering events
Event listeners can subscribe to specific events using one of several mechanisms:
@EventListener
public void handle( SomeEvent event ) {
// Called whenever an event of type SomeEvent is published
}
@EventListener( {SomeEvent.class, SomeOtherEvent.class} )
public void handleEvents() {
// In this case a method parameter is not actually required
}
@EventListener(condition = "#event.eventName == 'myEvent'")
public void handle( NamedEvent event ) {
// Called if the event is of type NamedEvent
// and property 'eventName' has the value 'myEvent'
}
@EventListener
public void onManCreated( EntityCreatedEvent<Man> event ) {
// Called if the generic type is exactly Man
}
@EventListener
public void onHumanCreated( EntityCreatedEvent<? extends Human> event ) {
// Called whenever the generic type implements Human
}
// The event must implement ResolvableTypeProvider if it is not a specific class
public class EntityCreatedEvent<T> implements ResolvableTypeProvider {
private final T entity;
public EntityCreatedEvent( T entity ) {
this.entity = entity;
}
@Override
public ResolvableType getResolvableType() {
return ResolvableType.forClassWithGenerics( getClass(), ResolvableType.forInstance( entity ) );
}
}
Asynchronous listeners
You can use a @Async
to handle events asynchronously.
This has some limitations, see the Spring framework documentation.
Please note as well that asynchronous execution must be enabled in the module where you register the event listener.
Ordering listeners
Ordering of listeners is one of the aspects where an Across application differs from default Spring ApplicationContext
behaviour.
When a module publishes an event, it will be received by all other modules in bootstrap order. This means that event listeners from a previous module might handle the event before listeners from the module that actually published it. By default, listener methods from the same across module do not have a specific order assigned.
The default ordering is reliable and works best for most use cases: you can rely on event listeners from previous modules having been executed before you. Thus, listeners registered in your application module will usually fire last.
Once an event has been handled by all modules, it will be sent to the (optional) parent ApplicationContext
.
Events published directly from a parent ApplicationContext - for example directly from within your @AcrossApplication class - will not be sent downstream to the modules!
|
Just like with other Across related ordering, you can influence the default behaviour:
-
use
@OrderInModule
on your methods to order listener execution within the same module -
use
@Order
on your methods to suppress the default module bootstrap order and order listeners explicitly