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="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:integration="http://www.springframework.org/schema/integration"
       xmlns:beans="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/integration http://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