Last Updated on July 27, 2024

Built on top of the Spring Framework, Spring Integration is designed to simplify the process of integrating different systems and applications. It provides a consistent and declarative way to connect various components, both within and outside of your application.

Architecture

Spring Integration comprises two core elements. Firstly, it acts as a messaging framework, facilitating lightweight, event-driven communication within an application. Secondly, it offers an adapter-based platform for seamlessly integrating diverse systems across the enterprise.

Fig. 1

Components within the same application messaging area of the diagram operate within a single Spring application context.

As they share the same JVM, message exchange is efficient and requires no serialization. Unlike traditional messaging systems, message payloads are primarily composed of POJO instances rather than XML, simplifying development and performance.

The interapplication integration domain utilizes adapters to bridge the gap between the application and external systems. Outbound messages are transformed into formats compatible with target systems, while inbound messages are converted into a format suitable for internal processing. Spring Integration offers a standardized approach to this mapping process, allowing for customization through adapter-specific implementations.

Enterprise Integration Patterns

Enterprise Integration Patterns (EIPs) are a set of reusable design patterns that provide solutions to common problems in integrating different systems and applications within an enterprise.

Core pattern categories encompass message handling, construction, routing, transformation, and endpoints. By understanding these patterns, developers can design robust, scalable, and maintainable integration architectures.

Message

They define how different system components communicate and exchange information. These patterns range from simple request-response interactions to complex asynchronous workflows. Key benefits include decoupling, scalability, and reliability. Messaging patterns are essential for building distributed systems, microservices architectures, and event-driven architectures.

A message typically consists of three primary components, Header contains metadata about the message itself, such as sender, recipient, timestamp, message type, correlation ID, and priority, body encapsulates the actual data or content being transmitted and properties, additional information related to the message, often used for routing, filtering, or processing.

These components provide the necessary structure for effective communication between systems. The specific format and content of each component can vary depending on the messaging protocol used

Message Channel

Message channels serve as the communication backbone between disparate system components. Their primary function is to decouple producers and consumers, abstracting away the complexities of message delivery. While channels can be implemented in various ways, from synchronous to asynchronous, their core responsibility remains consistent: facilitating message flow without interfering with message content.

Key channel characteristics include point-to-point and publish-subscribe models, each catering to distinct messaging scenarios. Regardless of the implementation, the channel’s primary goal is to ensure seamless message transfer between components.

Message Endpoint

Message endpoints are the operational hubs of a messaging system. They process incoming messages, performing actions ranging from simple routing to complex transformations. These endpoints can connect to external systems or internal components, serving as the bridge between the messaging framework and the application logic.

Essentially, message channels transport messages, while endpoints define their ultimate destination and purpose. A message’s journey concludes at an endpoint, and new messages are injected into the system through these points.

Spring Integration Example

Lets create a sample of two spring boot applications exchanging messages via Apache Artemis Broker.

In the following scheme we have 3 parties:

  1. Message Producer Application
  2. Apache Artemis message broker for message exchange
  3. Message Consumer application
+----------------+        +------------------+        +----------------+
|                |        |                  |        |                |
|    Producer    |------->|  Artemis Broker  |------->|    Consumer    |
|  Application   |        |    (Message      |        |  Application   |
|                |        |     Queue)       |        |                |
+----------------+        +------------------+        +----------------+
     |                            ^                         |
     |                            |                         |
     |                            |                         |
     |        sends messages      |     receives messages   |
     +----------------------------+-------------------------+

Broker

Download and extract Apache Artemis.

Open a terminal or command prompt and navigate to /bin directory and run the following command:

./artemis create mybroker

You’ll be prompted to enter various details:

  • Choose a username (default is “artemis”)
  • Choose a password(“password”)
  • Allow anonymous access? (typically “N” for security)

Navigate to mybroker/bin directory and run the following command:

./artemis run

You should see log output indicating that the broker has started

Consumer and Producer

Head to https://start.spring.io/ and generate basic spring boot project choosing java 17 for SDK.

Extract the downloaded zip and open it in intellij IDEA.

Add a module named Producer to the project.

Create a MessageProducer class:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;

@Component
public class MessageProducer {

    @Autowired
    private JmsTemplate jmsTemplate;

    public void sendMessage(String message) {
        jmsTemplate.convertAndSend("messageQueue", message);
        System.out.println("Message sent: " + message);
    }
}

In the main application class:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ProducerApplication implements CommandLineRunner {

    @Autowired
    private MessageProducer producer;

    public static void main(String[] args) {
        SpringApplication.run(ProducerApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        producer.sendMessage("Hello from Producer!");
    }
}

As a next step add a module named Consumer to the project.

Create MessageConsumer class.

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

@Component
public class MessageConsumer {

    @JmsListener(destination = "messageQueue")
    public void receiveMessage(String message) {
        System.out.println("Message received: " + message);
    }
}

The main application class:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}

Add following snippet to the pom.xml of both modules:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-artemis</artifactId>
    </dependency>
</dependencies>

and to application.properties:

spring.artemis.mode=native
spring.artemis.host=localhost
spring.artemis.port=61616
spring.artemis.user=artemis
spring.artemis.password=password

Now, run the modules.

The Producer will send a message to the “messageQueue”, and the Consumer will receive and print it.

Producer output:

Message sent: Hello from Producer!

Consumer output:

Message received:Hello from Producer!

This setup demonstrates two separate Spring Boot applications communicating via a JMS broker. The Producer sends messages to a queue, and the Consumer listens to that queue for incoming messages.

Scroll to Top