1.3 Main Components

From the vertical perspective, a layered architecture facilitates separation of concerns, and interface-based contracts between layers promote loose coupling. Spring-based applications are typically designed this way, and the Spring framework and portfolio provide a strong foundation for following this best practice for the full-stack of an enterprise application. Message-driven architectures add a horizontal perspective, yet these same goals are still relevant. Just as "layered architecture" is an extremely generic and abstract paradigm, messaging systems typically follow the similarly abstract "pipes-and-filters" model. The "filters" represent any component that is capable of producing and/or consuming messages, and the "pipes" transport the messages between filters so that the components themselves remain loosely-coupled. It is important to note that these two high-level paradigms are not mutually exclusive. The underlying messaging infrastructure that supports the "pipes" should still be encapsulated in a layer whose contracts are defined as interfaces. Likewise, the "filters" themselves would typically be managed within a layer that is logically above the application's service layer, interacting with those services through interfaces much in the same way that a web-tier would.

Message

In Spring Integration, a Message is a generic wrapper for any Java object combined with metadata used by the framework while handling that object. It consists of a payload and header and has a unique identifier. The payload can be of any type and the header holds commonly required information such as timestamp, expiration, and return address. Developers can also store any arbitrary key-value properties or attributes in the header.

Message Channel

A Message Channel represents the "pipe" of a pipes-and-filters architecture. Producers send Messages to a MessageChannel, and consumers receive Messages from a MessageChannel. The send and receive methods both come in two forms: one that blocks indefinitely and one that accepts a timeout (for an immediate return, specify a timeout value of 0). There are two main types of channels: Point-to-Point channels where typically a single consumer will receive the Message and Publish-Subscribe channels where all subscribers should receive the Message.

Message Endpoint

A Message Endpoint represents the "filter" of a pipes-and-filters architecture. The endpoint's primary role is to connect application code to the messaging framework and to do so in a non-invasive manner. In other words, the application code should have no awareness of the messaging framework. This is similar to the role of a Controller in the MVC paradigm. Just as a Controller handles HTTP requests, the endpoint handles Messages. Just as Controllers are mapped to URL patterns, endpoints are mapped to Message Channels. The goal is the same in both cases: isolate application code from the infrastructure. In Spring Integration, the Message Endpoint "hosts" and delegates to a MessageHandler strategy interface as described in Section 2.4, “MessageHandler”.

Message Router

A Message Router is a particular type of MessageHandler that is capable of receiving a Message and then deciding what channel or channels should receive the Message next. Typically the decision is based upon the Message's content and/or metadata. A Message Router is often used as a dynamic alternative to configuring the input and output channels for an endpoint.

Channel Adapter

A Channel Adapter is used to connect components to a Message Channel when those components are not themselves Message Endpoints. These adapters provide a mechanism for connecting to external systems, such as JMS queues or a File system. Channel Adapters may be configured for input and/or output. An input (source) adapter will receive (or poll for) data, convert that data to a Message, and then send that Message to its Message Channel. An output (target) adapter is simply another type of MessageHandler, but when it receives a Message, it will convert it to the target's expected type and then "send" it (publish to a JMS queue, write to a File, etc.).

Message Bus

The Message Bus acts as a registry for Message Channels and Message Endpoints. It also encapsulates the complexity of message retrieval and dispatching. Essentially, the Message Bus forms a logical extension of the Spring application context into the messaging domain. For example, it will automatically detect Message Channel and Message Endpoint components from within the application context. It handles the scheduling of pollers, the creation of thread pools, and the lifecycle management of all messaging components that can be initialized, started, and stopped. The Message Bus is the primary example of inversion of control within Spring Integration.