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.
The structure of the application is very simple:
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