A message bus offers facilities for publishing messages to registered listeners. Messages can be dispatched
synchronously or asynchronously and may be of any type that is a valid sub type of the type parameter T.
The dispatch mechanism can by controlled for per message handler and message publication.
A message publication is the publication of any message using one of the bus' publication methods.
Each message publication is isolated from all other running publications such that it does not interfere with them.
Hence, the bus expects message handlers to be stateless as it may invoke them concurrently if multiple
messages get published asynchronously.
A listener is any object that defines at least one message handler and that has been subscribed to at least
one message bus. A message handler can be any method that accepts exactly one parameter (the message) and is marked
as a message handler using the @Handler annotation.
The bus uses weak references to all listeners such that registered listeners do not need to
be explicitly unregistered to be eligible for garbage collection. Dead (garbage collected) listeners are
removed on-the-fly as messages get dispatched.
Generally message handlers will be invoked in inverse sequence of subscription but any
client using this bus should not rely on this assumption. The basic contract of the bus is that it will deliver
a specific message exactly once to each of the subscribed message handlers.
Messages are dispatched to all listeners that accept the type or supertype of the dispatched message. Additionally
a message handler may define filters to narrow the set of messages that it accepts.
Subscribed message handlers are available to all pending message publications that have not yet started processing.
Any message listener may only be subscribed once -> subsequent subscriptions of an already subscribed message listener
will be silently ignored)
Removing a listener (unsubscribing) means removing all subscribed message handlers of that listener. This remove operation
immediately takes effect and on all running dispatch processes -> A removed listener (a listener
is considered removed after the remove(Object) call returned) will under no circumstances receive any message publications.
Any running message publication that has not yet delivered the message to the removed listener will not see the listener
after the remove operation completed.
NOTE: Generic type parameters of messages will not be taken into account, e.g. a List
will
get dispatched to all message handlers that take an instance of List as their parameter