2.7 MessageBus

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.