So far, you have seen that the PollableChannel
provides a
receive()
method that returns a Message
, the subscribable
MessageChannels invoke one or more subscribers directly, and the MessageHandler
provides a handle()
method that accepts a Message
.
However, we have not yet discussed how messages get passed from a channel to a handler. As mentioned earlier,
the MessageBus
provides a runtime form of inversion of control, and one of the primary
responsibilities that it assumes is connecting the channels to the handlers. It also connects MessageSources and
MessageTargets to channels (thereby creating Channel Adapters), and it manages the scheduling of polling
dispatchers. Ultimately, every MessageHandler should be invoked as if it is an event-driven consumer, and this
works fine when the handler's input source is a SubscribableSource
. However, the
bus creates and manages these polling dispatchers so that even when handlers receive input from a
PollableSource
, they will still behave as event-driven consumers.
The MessageBus
is an example of a mediator. It performs a number of roles -
mostly by delegating to other strategies. One of its main responsibilities is to manage registration of the
MessageChannels
and endpoints, such as Channel Adapters
and Service Activators. It recognizes any of these instances that have been defined
within its ApplicationContext
.
The message bus handles several of the concerns so that the channels, sources, targets, and Message-handling objects can be as simple as possible. These responsibilities include the lifecycle management of message endpoints, the activation of subscriptions, and the scheduling of dispatchers (including the configuration of thread pools). The bus coordinates all of that behavior based upon the metadata provided in bean definitions. Furthermore, those bean definitions may be provided via XML and/or annotations (we will look at examples of both configuration options shortly).
The bus is responsible for activating all of its registered endpoints by connecting them to channels within its registry, and if necessary scheduling a poller so that the endpoint can be event-driven even when connected to a channel that requires polling. For example, the poller for an outbound Channel Adapter will poll the referenced "channel", and the poller for a Service Activator will poll the referenced "input-channel". If that "channel" or "input-channel" is subscribable rather than pollable, the bus will simply activate the subscription. The important point is that the endpoint itself does not need to know whether its source is pollable or subscribable.