Spring Integration Hello World tutorial


Here you can find another Hello World example that shows the first steps to build a Spring Integration application.

In our example we create a new Java application that send a message ‘World’ to a channel, a Spring service receives and modifies this string (‘Hello World!’). Eventually and the message is sent to a print service through a second channel.

spring_integration_1

The structure of the application is very simple:

spring_integration_2

You can find all the code on gitHub: https://github.com/marco76/SpringIntegrationExamples

The project is build with maven (and developed using IntelliJ). In the pom.xml you have to import the usual libraries and Spring Integration:

<dependency> 
    <groupId>org.springframework.integration</groupId> 
    <artifactId>spring-integration-core</artifactId> 
    <version>2.2.3.RELEASE</version> 
</dependency> 

The spring-config.xml configure the channels used by the application:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="https://www.springframework.org/schema/beans" 
       xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" 
       xmlns:context="https://www.springframework.org/schema/context" 
       xmlns:integration="https://www.springframework.org/schema/integration" 
       xmlns:beans="https://www.springframework.org/schema/beans" 
       xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd https://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd"> 
 
    <context:annotation-config /> 
 
    <context:component-scan base-package="ch.javaee.integration.example.helloWorld"/> 
 
    <!-- this channel is called by the application and the message is passed to it --> 
    <integration:channel id="inputChannel"/> 
 
    <!-- this channel receive the modified message --> 
    <integration:channel id="outputChannel"/> 
 
    <!-- this service transform the message in input-channel and send the result to output-channel --> 
    <!-- the service method to call is referenced in explicitly --> 
    <integration:service-activator input-channel="inputChannel" ref="helloService" method="sayHello" output-channel="outputChannel"/> 
 
    <!-- this service receives a message and pass it to printerService --> 
    <!-- the method that consumes the message is implicitly defined by the @ServiceActivator annotation or it should be the only 
    method in the class --> 
    <integration:service-activator input-channel="outputChannel" ref="printerService"/> 
 
</beans> 

We have 2 channels that are used to transfer messages between services. The service-activator wait for messages sent to the input-channel it call a predefined service (ex. helloService). If the called service returns a value this value is sent to the output-channel.

/** 
 * The goal of this example is to show how a message can be sent to one input channel, 
 * be transformed by a service, sent to a second channel and consumed by a second service 
 */ 
public class HelloApp { 
    public static void main(String[] args) { 
 
        // load the Spring context 
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); 
 
        // get the reference to the message channel 
        MessageChannel channel = context.getBean("inputChannel", MessageChannel.class); 
 
        // create a message with the content "World" 
        Message<String> message = MessageBuilder.withPayload("World").build(); 
 
        // send the message to the inputChannel 
        channel.send(message); 
    } 
} 

The main class of the application (HelloApp) load the spring beans and send a message to the inputChannel.

The service-activator read the message and pass it to method sayHello helloService:

<integration:channel id="inputChannel"/> 
<integration:service-activator input-channel="inputChannel" ref="helloService" method="sayHello" output-channel="outputChannel"/> 
/** 
 * This service simply modify the original message and return the new message 
 */ 
@Component 
public class HelloService { 
 
    public String sayHello(String name) { 
        return "Hello " + name + "!"; 
    } 
} 

HelloService is a simple bean Spring (@Component), it doesn’t know anything about Spring integration.

The method sayHello return a String value (“Hello ” + “world” + “!”). Spring send this string to the output-channel defined in the configuration.

<integration:channel id="outputChannel"/> 
<integration:service-activator input-channel="outputChannel" ref="printerService"/> 

In this case we don’t need to define which method will receive the message. Spring doesn’t need to explicitly know the name if:

– there is only one method in the class

– the method is annotated with @ServiceActivator (as in our case)

/** 
 * This service consume the message and print it on the console 
 */ 
 
@Component 
public class PrinterService { 
 
    // if only one method is present in the class the @ServiceActivator is not necessary 
    // in alternative the method has to be explicitly declared in the configuration 
 
    @ServiceActivator 
    public void printValue(String value){ 
        System.out.println(value); 
    } 
} 

The PrinterService receive the message from outputChannel and print it (“Hello World!”) to the console. The method should not return any value to avoid the following error:

Exception in thread “main” org.springframework.integration.support.channel.ChannelResolutionException: no output-channel or replyChannel header available



WebApp built by Marco using SpringBoot, Java 17, Mustache, Markdown and in Azure