Spring Integration Demystified
Background
In almost all software projects we’re going to have to make our software connect to other systems. Often this involves writing lots of plumbing code, which is code that’s not about the real business logic of our application and that takes a lot of time to write and maintain. Spring Integration promises to solve this problem by providing an Adapter and Channel based approaches.
When we are building microservices we need to communicate with each individual services either through Http (Synchronous) or TCP (Asynchronous). Synchronous communication using Http REST tends to decrease the throughput of the system hence better approach is event-driven or message-driven approach which is asynchronous. Spring Integration makes communication with multiple microservices very easy by using messages, without knowing much about the underlying transportation details of the messages.
Enterprise Application Integration
To understand Spring Integration better we first need to have some basic understanding of Enterprise Application Integration (EAI) patterns. EAI focusses on integrating applications and data using a set of well-known patterns which are often termed as EAI patterns in software engineering. These patterns are usefully summarized and embodied in a landmark book called Enterprise Integration Patterns, by Gregor Hohpe, Bobby Woolf, and colleagues. This book is kind of a starting point which motivated the creators of the Spring Framework to build something which implements those patterns given in the book by creating a dedicated project known as Spring Integration. It is advisable for every developer to read the book who want to know system integration in depth. The link of the book is given as below:
Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions
Home — Enterprise Integration Patterns
In quick words, EAI patterns provides a solution to having one or more applications that need to talk to each other through external interfaces and establish a connection between the applications’ services and/or their data.
There are around 4 important Integration requirements which are as below:
1. File transfer: Have each application produce files of shared data for others to consume and consume files that others have produced.
2. Shared Database
3. Remote Method Invocation
4. Messaging
Out of these File Transfer and Messaging are the most used ones. But, as part of this edition of this blog post we will only explore message integrations.
Before going into individual concepts let me give a flavor of how a real-world enterprise integration comprising of various system looks like. The below diagram is a typical example of an Order Processing Implementation using Asynchronous Messaging.
We will understand each of the given terms in this blog post later.
Why we need a Messaging based system?
In earlier days, around 15–20 years back messaging was not a popular solution to integrate external systems. Let's, have quick what was the problem with that system.
Consider, we have System A and System B which needs to be connected. At this point of time, it is fairly manageable since it has only 2 relationships as given in the below diagram.
However, if we add more systems as below the math can be quickly overwhelming. If we add System C and System D to the existing ones we will be end up having around 10–12 relationships just for 4 nodes as given below:
So, to solve this problem people used to force everything through a common message endpoint/queue/bus where the bus maintains the relationship with each individual systems, but it can't canonicalize the data that travels through it and henceforth each system only knows how to connect with the bus but not the individual systems and thus reducing the network of system. This works but not a good approach in modern systems since the service bus is the single point of failure as it's creating a bottleneck when the traffic increases. This is where messaging solution comes to the rescue and today it's the de-facto integration style between systems.
Now let's understand some of the EAI Terms in brief which forms a base for Spring Integration.
Message
- Unit of Information- A message is a unit of data that is transmitted from a sender to one or more receivers via a messaging system.
- Encapsulates data
- Passed between endpoints
- Consists of two parts, the payload and headers (Similar to a HTTP Request)
- The payload is the actual content of the message. This can be any kind of data, and the meaning of the payload is application specific.
- The headers of the message contain metadata, which can be anything that the messaging system needs to deliver the message to the receiver, for example, a unique ID, timestamp, correlation ID.
Message Channels
- Abstract idea of something that carries messages from a sender to a receiver
- There are many different ways to implement message channels. Queues are an example, but a message channel is not always a queue.
- There are two main types of message channels, which are Point-to-Point Channels and Publish-Subscribe Channels.
Point-to-Point Channels
A Point-to-Point Channel is a message channel that connects exactly one sender with exactly one receiver. One possible implementation of Point-to-Point Channels are queues.
Publish-Subscribe Channels
A Publish-Subscribe Channel is used to broadcast messages from one sender to multiple receivers. One common scenario where you would want to use a Publish-Subscribe Channel is to broadcast event notifications to parts of your software that are interested in particular types of events.
Message Endpoint
A message endpoint is the part of the code of a sender and a receiver that connects to the messaging system. This is a very general idea, and there are more patterns that describe more specific types of message endpoints, such as channel adapters, gateways, and service activators.
Spring Integration
- A Framework built on top of Core Spring Platform that helps us solve Integration problems by talking to disparate system which don’t know each other.
- At its core it has an Embedded Message Bus. Messages are sent back and forth between components in the same way as we work with JMS/AMQP.
- It is an Application Integration Framework, which provides adapter components to connect with external systems.
- Spring Integration is an implementation of the Enterprise Integration Patterns, which enables us to write our own Spring-based applications that use the patterns. It contains many ready-to-use implementations of the concepts of Enterprise Integration Patterns in the form of interfaces and classes that are designed with the main principles of the Spring Framework in mind. It has interfaces and classes for messages, different kinds of message channels, many different kinds of endpoints, and transformers and routers. We can use these components using the standard Spring Framework programming techniques, such as dependency injection, which helps us to maintain separation of concerns between business logic and integration logic.
- It’s used as the basis for other Spring Framework projects such as Spring Cloud Stream for building highly scalable event-driven microservices.
Now, let's quickly look at some Spring Integration specific concepts.
Spring Integration Message
- Payload can be any object
- Header values are stored in read-only
java.util.Map<K,V>
- Similar to JMS Messages, email mime envelopes, XMPP messages etc.
Spring Integration Endpoints
- Transformer- converts payload and modify headers
2. Filter- discard messages based on test
3. Router- determine next channel based on message and test
4. Splitter- generate multiple messages from one
5. Aggregator- Assemble a single message from multiple message
Service Activator
It delegates processing to a backend service call. It’s a way for us to call Java code and use the resultant value in the integration pipeline.
Adapter
Spring Integration helps us to connect to external systems. It does that with the help of Adapters and Gateways.
It is a unidirectional component that takes data from an external system and then either converts it into a Spring Integration Message or takes a Spring Integration Message and adapts it to another external system.
The below diagram is an illustration of an outbound adapter that sends message to ActiveMQ broker.
Inbound adapter is exactly opposite of the same. The below diagram also illustrates the same with the help of a File Inbound adapter which polls file from a directory and uses the same file in its system referred as consumer.
With this we have mostly covered the essential topics and concepts related to Spring Integration, but would still recommend looking into the official documentation given by the Spring Team as below:
This blog post was mostly theoretical. In the next edition we will try to look into some practical implementations using some external systems which will help us to understand the framework better.
Thanks! See you in next post.