2017-09-08 1 views
1

Depuis la documentation EventBus de la goyave est assez court je demande ici:Goyave EventBus: événement Dispatching aux abonnés multiples

est-il un moyen de distribuer des événements à plusieurs abonnés ou sont des événements toujours consommés par le premier abonné approprié?

Si ce dernier cas est le cas, est-il préférable d'étendre la classe EventBus afin d'ajouter une telle fonctionnalité ou d'implémenter toute la logique de bus d'événement dans sa propre application?

Répondre

1

Les événements sont routés vers tous les abonnés enregistrés tant qu'ils correspondent au type d'événement.

Il est dans les Javadoc de EventBus:

Events postage

Pour poster un événement, il suffit de fournir l'objet d'événement à la méthode post (Object). L'occurrence EventBus détermine le type d'événement et l'achemine vers tous les écouteurs enregistrés.

Les événements sont routés en fonction de leur type - un événement sera envoyé à n'importe quel abonné pour tout type auquel l'événement est assignable. Cela inclut les interfaces implémentées, toutes les superclasses et toutes les interfaces implémentées par les superclasses.

+0

Merci beaucoup - J'ai lu et testé ça mais mon test n'était pas valide: je n'ai pas enregistré le second auditeur ;-) – Hannes

0

Si ce dernier est le cas, serait-il préférable d'étendre la classe EventBus afin d'ajouter une telle fonctionnalité ou à mettre en œuvre toute la logique de bus d'événement dans la propre application?

Je suppose que, tout ce que vous avez besoin est d'ajouter un attribut handled à l'événement et ajouter un testAndSet à tous vos gestionnaires. Le faire manuellement est sûrement sujet aux erreurs, si vous en avez beaucoup.

Vous pouvez créer un wrapper pour votre événement, ce qui ne vous permettrait pas d'y accéder sans l'appeler. Quelque chose comme

@RequiredArgsConstructor 
class WrappedEvent<E extends MyEvent> { 
    private final E event; 
    private boolean handled; 

    Optional<E> getAndMarkHandledUnlessHandled() { 
     if (handled) { 
      return Optional.empty(); 
     } else { 
      handled = true; 
      return Optional.of(event); 
     } 
    } 
} 

ou le faire de manière plus fonctionnelle comme callAndMarkHandledUnlessHandled(Consumer<E> consumer). Pour l'envoi asynchrone, vous devez utiliser un AtomicBoolean.

Cependant, en raison de l'effacement, cela ne fonctionnera pas avec WrappedEvent<A> et WrappedEvent<B> car le EventBus n'a pas d'information générique disponible. Vous pourriez sous-classer le wrapper comme WrappedA extends WrappedEvent<A> {} et travailler avec. C'est sacrément moche.

L'extension significative du EventBus n'est guère possible, si vous ne voulez pas vous faufiler dans son emballage. Le moyen le plus simple serait probablement de forcer l'ensemble du paquet et d'ajouter une pause après this line.