Hello World Using Spring Integration

Hello World Using Spring Integration

0 Comments

Spring Integration is a very powerful module in the Spring Framework. It was originally inspired by pivotal book in computer science called Enterprise Integration Patterns written by Gregor Hohpe and Bobby Woolf. While the Gang of Four focused their work on software design patterns, Enterprise Integration Patterns is focused on how disparate systems communicate with each other. As the industry has moved to highly scalable systems adopting cloud computing paradigms, the principles set forth in Enterprise Integration Patterns are highly relevant to Java programming.

Similar to the GoF focus, Spring Core largely focused on development within a single application or JVM environment.  Spring Integration builds upon the core principles of Spring Core to extend the Spring programming model to a message driven programming model. Abstracted from the developer when making a method call is the implementation details. Does it really matter if the method you are calling is a simple method call, a web service, a JMS Message, or making a request to the database? No, it should not. And more importantly, the implementation details should not leak back into your code.

In this example, I’ll step through the use of a Spring Integration Message Gateway for a classic “Hello World” programming example. I’ll show you how to use a Spring Integration Messaging Gateway for a simple send message, a request / response example, and an async request response example.

Spring Integration Hello World Code Example

Hello World Service Bean

For our example, we’re going to use a very simple service bean to either say hello or get a hello message. In a real world example, this code could be a direct method call, behind a web service, or perhaps its a message driven bean off a AQMP queue.

package guru.springframework.hello.world.si.service;

import org.springframework.stereotype.Service;

@Service
public class HelloService {
    public void sayHello(String name) {
        System.out.println("Hello " + name + "!!");
    }

    public String getHelloMessage(String name){
        return ("Hello " + name + "!!");
    }
}

Spring Integration Gateway

The next component we need to setup is an interface class, which we will use for the Spring Integration Gateways. When coding to use Spring Integration, messaging gateways are a very convenient programming option to use. They have a very minimal impact on your application code. As the developer, you only need to create the interface specification. Spring Integration will provide the actual implementation and inject it into your class at run time. There is one small bit of leakage into your application code with the @Gateway  annotation. I could have coded this example without the annotations, but I find them very convenient to use. This annotation directs Spring Integration which messaging channel to use for the method call of the interface.

package guru.springframework.hello.world.si.gateways;

import org.springframework.integration.annotation.Gateway;

import java.util.concurrent.Future;

public interface HelloWorldGateway {
    @Gateway(requestChannel = "say.hello.channel")
    void sayHello(String name);

    @Gateway(requestChannel = "get.hello.channel")
    String getHelloMessage(String name);

    @Gateway(requestChannel = "get.hello.channel")
    Future getHelloMessageAsync(String name);
}

Spring Integration Gateway Configuration

The messaging gateway needs to be defined in your Spring Integration configuration. Spring Integration will not create the gateway bean without this configuration line.

<gateway id="helloWorldGateway" service-interface="guru.springframework.hello.world.si.gateways.HelloWorldGateway"/>

Spring Integration Channel

Spring Integration Channels are a core concept to Spring Integration. They are used to decouple message producers (our gateway) from message consumers (our hello world bean). This abstraction is important because the channel could be a direct method call, or a JMS queue. The important take away is the decoupling. Neither the message producer nor the message consumer is aware of details about the implementation of the messaging channel.

In XML configuration snippet below, I’ve defined two messaging channels. Spring Integration has a number of options for defining messaging channels. The default channel is a direct channel, which is perfect for our hello world example.

    <channel id="say.hello.channel"/>

    <channel id="get.hello.channel"/>

Spring Integration Service Activator

Spring Integration has a concept of Service Activators. This is basically a way to configure a message consumer on a channel. This is completely decoupled from the gateway. Its important to remember the service activator is associated with a channel, and not a gateway or a gateway method. When you’re new to Spring Integration, it can be easy to lose site of this important distinction.

In this XML configuration snippet, I’ve defined two service activators.

    <service-activator id="sayHello" input-channel="say.hello.channel" ref="helloService" method="sayHello"/>

    <service-activator id="getHello" input-channel="get.hello.channel" ref="helloService" method="getHelloMessage"/>

Spring Integration XML Configuration

The complete XML configuration used in our hello world example follows below. You’ll see that I’m using a component scan to create the Hello World Service bean in the Spring context.

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                  http://www.springframework.org/schema/beans/spring-beans.xsd
                  http://www.springframework.org/schema/integration
                  http://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="guru.springframework.hello.world.si.service"/>

    <gateway id="helloWorldGateway" service-interface="guru.springframework.hello.world.si.gateways.HelloWorldGateway"/>

    <channel id="say.hello.channel"/>

    <service-activator id="sayHello" input-channel="say.hello.channel" ref="helloService" method="sayHello"/>

    <channel id="get.hello.channel"/>

    <service-activator id="getHello" input-channel="get.hello.channel" ref="helloService" method="getHelloMessage"/>

</beans:beans>

Running the Spring Integration Hello World Example

I’ve setup two examples to run our Spring Integration Hello World example. One using Spring Boot, and the second using JUnit.

Spring Boot Application

In this example, I’m using Spring Boot to bring up the Spring Context. Since I placed the Spring Integration configuration in a XML configuration file, I need to use the @ImportResource  annotation to tell Spring Boot to import the XML configuration file.  In the code, I ask the Spring Context for an instance of the gateway bean. Then I call our three methods. The first is a simple send message with no return value. Our messaging service bean will write the hello message to the console. In the second example, I’m getting a message back from the Hello World Service bean.  The final example is a little more interesting. In this case, I’ve setup an asynchronous call. By specifying a Future in the return type, Spring Integration will automatically make a asynchronous call. This is an ideal technique to use when you have a longer running call (such as a remote web service), and you can do other work while the call is being made.

package guru.springframework.hello.world.si;

import guru.springframework.hello.world.si.gateways.HelloWorldGateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportResource;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@SpringBootApplication
@ImportResource("classpath*:/spring/si-config.xml")
public class HelloWorldSiApplication {

    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(HelloWorldSiApplication.class, args);
        HelloWorldGateway gateway = (HelloWorldGateway) ctx.getBean("helloWorldGateway");
        gateway.sayHello("John");

        String message = gateway.getHelloMessage("John (get message)");
        System.out.println(message);

        Future helloFuture = gateway.getHelloMessageAsync("John (Async!)");

        try {
            String helloFutureMsg = helloFuture.get();
            System.out.println(helloFutureMsg);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }
}

When you execute the above code, you will receive the following output in the console.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.2.3.RELEASE)

2015-04-08 10:35:29.665  INFO 11513 --- [           main] g.s.h.world.si.HelloWorldSiApplication   : Starting HelloWorldSiApplication on Johns-MacBook-Pro.local with PID 11513 (/Users/jt/src/springframework.guru/blog/hello-world-si/target/classes started by jt in /Users/jt/src/springframework.guru/blog/hello-world-si)
2015-04-08 10:35:29.773  INFO 11513 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.spring[email protected]8646db9: startup date [Wed Apr 08 10:35:29 EDT 2015]; root of context hierarchy
2015-04-08 10:35:30.827  INFO 11513 --- [           main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from URL [file:/Users/jt/src/springframework.guru/blog/hello-world-si/target/classes/spring/si-config.xml]
2015-04-08 10:35:31.104  INFO 11513 --- [           main] o.s.b.f.config.PropertiesFactoryBean     : Loading properties file from URL [jar:file:/Users/jt/.m2/repository/org/springframework/integration/spring-integration-core/4.1.2.RELEASE/spring-integration-core-4.1.2.RELEASE.jar!/META-INF/spring.integration.default.properties]
2015-04-08 10:35:31.113  INFO 11513 --- [           main] o.s.i.config.IntegrationRegistrar        : No bean named 'integrationHeaderChannelRegistry' has been explicitly defined. Therefore, a default DefaultHeaderChannelRegistry will be created.
2015-04-08 10:35:31.367  INFO 11513 --- [           main] faultConfiguringBeanFactoryPostProcessor : No bean named 'errorChannel' has been explicitly defined. Therefore, a default PublishSubscribeChannel will be created.
2015-04-08 10:35:31.375  INFO 11513 --- [           main] faultConfiguringBeanFactoryPostProcessor : No bean named 'taskScheduler' has been explicitly defined. Therefore, a default ThreadPoolTaskScheduler will be created.
2015-04-08 10:35:31.594  INFO 11513 --- [           main] o.s.b.f.config.PropertiesFactoryBean     : Loading properties file from URL [jar:file:/Users/jt/.m2/repository/org/springframework/integration/spring-integration-core/4.1.2.RELEASE/spring-integration-core-4.1.2.RELEASE.jar!/META-INF/spring.integration.default.properties]
2015-04-08 10:35:31.595  INFO 11513 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'integrationGlobalProperties' of type [class org.springframework.beans.factory.config.PropertiesFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-04-08 10:35:31.595  INFO 11513 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'integrationGlobalProperties' of type [class java.util.Properties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-04-08 10:35:31.598  INFO 11513 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'messageBuilderFactory' of type [class org.springframework.integration.support.DefaultMessageBuilderFactory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-04-08 10:35:31.688  INFO 11513 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean '(inner bean)#d771cc9' of type [class org.springframework.integration.channel.MessagePublishingErrorHandler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-04-08 10:35:31.688  INFO 11513 --- [           main] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService  'taskScheduler'
2015-04-08 10:35:31.690  INFO 11513 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'taskScheduler' of type [class org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-04-08 10:35:31.690  INFO 11513 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'integrationHeaderChannelRegistry' of type [class org.springframework.integration.channel.DefaultHeaderChannelRegistry] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-04-08 10:35:31.846  INFO 11513 --- [           main] ProxyFactoryBean$MethodInvocationGateway : started helloWorldGateway
2015-04-08 10:35:31.846  INFO 11513 --- [           main] ProxyFactoryBean$MethodInvocationGateway : started helloWorldGateway
2015-04-08 10:35:31.846  INFO 11513 --- [           main] ProxyFactoryBean$MethodInvocationGateway : started helloWorldGateway
2015-04-08 10:35:31.846  INFO 11513 --- [           main] o.s.i.gateway.GatewayProxyFactoryBean    : started helloWorldGateway
2015-04-08 10:35:32.235  INFO 11513 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2015-04-08 10:35:32.244  INFO 11513 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase -2147483648
2015-04-08 10:35:32.246  INFO 11513 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
2015-04-08 10:35:32.247  INFO 11513 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {service-activator:sayHello} as a subscriber to the 'say.hello.channel' channel
2015-04-08 10:35:32.247  INFO 11513 --- [           main] o.s.integration.channel.DirectChannel    : Channel 'application.say.hello.channel' has 1 subscriber(s).
2015-04-08 10:35:32.247  INFO 11513 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started sayHello
2015-04-08 10:35:32.248  INFO 11513 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {service-activator:getHello} as a subscriber to the 'get.hello.channel' channel
2015-04-08 10:35:32.248  INFO 11513 --- [           main] o.s.integration.channel.DirectChannel    : Channel 'application.get.hello.channel' has 1 subscriber(s).
2015-04-08 10:35:32.248  INFO 11513 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started getHello
2015-04-08 10:35:32.248  INFO 11513 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2015-04-08 10:35:32.248  INFO 11513 --- [           main] o.s.i.channel.PublishSubscribeChannel    : Channel 'application.errorChannel' has 1 subscriber(s).
2015-04-08 10:35:32.248  INFO 11513 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started _org.springframework.integration.errorLogger
2015-04-08 10:35:32.256  INFO 11513 --- [           main] g.s.h.world.si.HelloWorldSiApplication   : Started HelloWorldSiApplication in 3.063 seconds (JVM running for 3.829)
Hello John!!
Hello John (get message)!!
Hello John (Async!)!!
2015-04-08 10:35:32.284  INFO 11513 --- [       Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.spring[email protected]8646db9: startup date [Wed Apr 08 10:35:29 EDT 2015]; root of context hierarchy
2015-04-08 10:35:32.285  INFO 11513 --- [       Thread-1] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase 0
2015-04-08 10:35:32.285  INFO 11513 --- [       Thread-1] ProxyFactoryBean$MethodInvocationGateway : stopped helloWorldGateway
2015-04-08 10:35:32.286  INFO 11513 --- [       Thread-1] ProxyFactoryBean$MethodInvocationGateway : stopped helloWorldGateway
2015-04-08 10:35:32.286  INFO 11513 --- [       Thread-1] ProxyFactoryBean$MethodInvocationGateway : stopped helloWorldGateway
2015-04-08 10:35:32.286  INFO 11513 --- [       Thread-1] o.s.i.gateway.GatewayProxyFactoryBean    : stopped helloWorldGateway
2015-04-08 10:35:32.286  INFO 11513 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : Removing {service-activator:sayHello} as a subscriber to the 'say.hello.channel' channel
2015-04-08 10:35:32.286  INFO 11513 --- [       Thread-1] o.s.integration.channel.DirectChannel    : Channel 'application.say.hello.channel' has 0 subscriber(s).
2015-04-08 10:35:32.286  INFO 11513 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : stopped sayHello
2015-04-08 10:35:32.286  INFO 11513 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : Removing {service-activator:getHello} as a subscriber to the 'get.hello.channel' channel
2015-04-08 10:35:32.286  INFO 11513 --- [       Thread-1] o.s.integration.channel.DirectChannel    : Channel 'application.get.hello.channel' has 0 subscriber(s).
2015-04-08 10:35:32.286  INFO 11513 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : stopped getHello
2015-04-08 10:35:32.287  INFO 11513 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : Removing {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2015-04-08 10:35:32.287  INFO 11513 --- [       Thread-1] o.s.i.channel.PublishSubscribeChannel    : Channel 'application.errorChannel' has 0 subscriber(s).
2015-04-08 10:35:32.287  INFO 11513 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : stopped _org.springframework.integration.errorLogger
2015-04-08 10:35:32.287  INFO 11513 --- [       Thread-1] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase -2147483648
2015-04-08 10:35:32.288  INFO 11513 --- [       Thread-1] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown
2015-04-08 10:35:32.290  INFO 11513 --- [       Thread-1] o.s.s.c.ThreadPoolTaskScheduler          : Shutting down ExecutorService 'taskScheduler'

JUnit Example

We can run the same code as a JUnit test as well. In this case, I’m allowing Spring to autowire the Spring Integration gateway into my test. Then I have three separate tests to execute our three different hello world examples.

This is more typical of how you would use a Spring Integration gateway in your application code. You can utilize dependency injection in Spring to inject an instance of the Spring Integration gateway instance into your class at run time.

package guru.springframework.hello.world.si;

import guru.springframework.hello.world.si.gateways.HelloWorldGateway;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = HelloWorldSiApplication.class)
public class HelloWorldSiApplicationTests {

	@Autowired
	HelloWorldGateway helloWorldGateway;

	@Test
	public void sayHelloTest() {
		helloWorldGateway.sayHello("John");
	}

	@Test
	public void getHelloMessageTest(){
		String message = helloWorldGateway.getHelloMessage("John (get message)");
		System.out.println(message);
	}

	@Test
	public void getHelloAsycTest() throws ExecutionException, InterruptedException {
		Future helloFuture = helloWorldGateway.getHelloMessageAsync("John (Woot, Asyc)");
		String message = helloFuture.get();
		System.out.println(message);
	}

}

When you run the JUnit tests in this class, you will get the following output in the console.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.2.3.RELEASE)

2015-04-08 10:44:06.520  INFO 11548 --- [           main] c.i.rt.execution.junit.JUnitStarter      : Starting JUnitStarter on Johns-MacBook-Pro.local with PID 11548 (started by jt in /Users/jt/src/springframework.guru/blog/hello-world-si)
2015-04-08 10:44:06.619  INFO 11548 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.spring[email protected]27ae2fd0: startup date [Wed Apr 08 10:44:06 EDT 2015]; root of context hierarchy
2015-04-08 10:44:07.577  INFO 11548 --- [           main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from URL [file:/Users/jt/src/springframework.guru/blog/hello-world-si/target/classes/spring/si-config.xml]
2015-04-08 10:44:07.875  INFO 11548 --- [           main] o.s.b.f.config.PropertiesFactoryBean     : Loading properties file from URL [jar:file:/Users/jt/.m2/repository/org/springframework/integration/spring-integration-core/4.1.2.RELEASE/spring-integration-core-4.1.2.RELEASE.jar!/META-INF/spring.integration.default.properties]
2015-04-08 10:44:07.885  INFO 11548 --- [           main] o.s.i.config.IntegrationRegistrar        : No bean named 'integrationHeaderChannelRegistry' has been explicitly defined. Therefore, a default DefaultHeaderChannelRegistry will be created.
2015-04-08 10:44:08.123  INFO 11548 --- [           main] faultConfiguringBeanFactoryPostProcessor : No bean named 'errorChannel' has been explicitly defined. Therefore, a default PublishSubscribeChannel will be created.
2015-04-08 10:44:08.126  INFO 11548 --- [           main] faultConfiguringBeanFactoryPostProcessor : No bean named 'taskScheduler' has been explicitly defined. Therefore, a default ThreadPoolTaskScheduler will be created.
2015-04-08 10:44:08.289  INFO 11548 --- [           main] o.s.b.f.config.PropertiesFactoryBean     : Loading properties file from URL [jar:file:/Users/jt/.m2/repository/org/springframework/integration/spring-integration-core/4.1.2.RELEASE/spring-integration-core-4.1.2.RELEASE.jar!/META-INF/spring.integration.default.properties]
2015-04-08 10:44:08.290  INFO 11548 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'integrationGlobalProperties' of type [class org.springframework.beans.factory.config.PropertiesFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-04-08 10:44:08.291  INFO 11548 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'integrationGlobalProperties' of type [class java.util.Properties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-04-08 10:44:08.295  INFO 11548 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'messageBuilderFactory' of type [class org.springframework.integration.support.DefaultMessageBuilderFactory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-04-08 10:44:08.537  INFO 11548 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean '(inner bean)#76012793' of type [class org.springframework.integration.channel.MessagePublishingErrorHandler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-04-08 10:44:08.538  INFO 11548 --- [           main] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService  'taskScheduler'
2015-04-08 10:44:08.541  INFO 11548 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'taskScheduler' of type [class org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-04-08 10:44:08.542  INFO 11548 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'integrationHeaderChannelRegistry' of type [class org.springframework.integration.channel.DefaultHeaderChannelRegistry] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-04-08 10:44:08.991  INFO 11548 --- [           main] ProxyFactoryBean$MethodInvocationGateway : started helloWorldGateway
2015-04-08 10:44:08.991  INFO 11548 --- [           main] ProxyFactoryBean$MethodInvocationGateway : started helloWorldGateway
2015-04-08 10:44:08.991  INFO 11548 --- [           main] ProxyFactoryBean$MethodInvocationGateway : started helloWorldGateway
2015-04-08 10:44:08.991  INFO 11548 --- [           main] o.s.i.gateway.GatewayProxyFactoryBean    : started helloWorldGateway
2015-04-08 10:44:09.309  INFO 11548 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase -2147483648
2015-04-08 10:44:09.312  INFO 11548 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
2015-04-08 10:44:09.312  INFO 11548 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {service-activator:sayHello} as a subscriber to the 'say.hello.channel' channel
2015-04-08 10:44:09.313  INFO 11548 --- [           main] o.s.integration.channel.DirectChannel    : Channel 'application:-1.say.hello.channel' has 1 subscriber(s).
2015-04-08 10:44:09.314  INFO 11548 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started sayHello
2015-04-08 10:44:09.314  INFO 11548 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {service-activator:getHello} as a subscriber to the 'get.hello.channel' channel
2015-04-08 10:44:09.314  INFO 11548 --- [           main] o.s.integration.channel.DirectChannel    : Channel 'application:-1.get.hello.channel' has 1 subscriber(s).
2015-04-08 10:44:09.315  INFO 11548 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started getHello
2015-04-08 10:44:09.315  INFO 11548 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2015-04-08 10:44:09.316  INFO 11548 --- [           main] o.s.i.channel.PublishSubscribeChannel    : Channel 'application:-1.errorChannel' has 1 subscriber(s).
2015-04-08 10:44:09.316  INFO 11548 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started _org.springframework.integration.errorLogger
2015-04-08 10:44:09.326  INFO 11548 --- [           main] c.i.rt.execution.junit.JUnitStarter      : Started JUnitStarter in 3.267 seconds (JVM running for 4.367)
Hello John (Woot, Asyc)!!
Hello John!!
Hello John (get message)!!
2015-04-08 10:44:09.367  INFO 11548 --- [       Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.spring[email protected]27ae2fd0: startup date [Wed Apr 08 10:44:06 EDT 2015]; root of context hierarchy
2015-04-08 10:44:09.368  INFO 11548 --- [       Thread-1] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase 0
2015-04-08 10:44:09.369  INFO 11548 --- [       Thread-1] ProxyFactoryBean$MethodInvocationGateway : stopped helloWorldGateway
2015-04-08 10:44:09.369  INFO 11548 --- [       Thread-1] ProxyFactoryBean$MethodInvocationGateway : stopped helloWorldGateway
2015-04-08 10:44:09.369  INFO 11548 --- [       Thread-1] ProxyFactoryBean$MethodInvocationGateway : stopped helloWorldGateway
2015-04-08 10:44:09.369  INFO 11548 --- [       Thread-1] o.s.i.gateway.GatewayProxyFactoryBean    : stopped helloWorldGateway
2015-04-08 10:44:09.369  INFO 11548 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : Removing {service-activator:sayHello} as a subscriber to the 'say.hello.channel' channel
2015-04-08 10:44:09.369  INFO 11548 --- [       Thread-1] o.s.integration.channel.DirectChannel    : Channel 'application:-1.say.hello.channel' has 0 subscriber(s).
2015-04-08 10:44:09.369  INFO 11548 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : stopped sayHello
2015-04-08 10:44:09.369  INFO 11548 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : Removing {service-activator:getHello} as a subscriber to the 'get.hello.channel' channel
2015-04-08 10:44:09.369  INFO 11548 --- [       Thread-1] o.s.integration.channel.DirectChannel    : Channel 'application:-1.get.hello.channel' has 0 subscriber(s).
2015-04-08 10:44:09.370  INFO 11548 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : stopped getHello
2015-04-08 10:44:09.370  INFO 11548 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : Removing {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2015-04-08 10:44:09.370  INFO 11548 --- [       Thread-1] o.s.i.channel.PublishSubscribeChannel    : Channel 'application:-1.errorChannel' has 0 subscriber(s).
2015-04-08 10:44:09.370  INFO 11548 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : stopped _org.springframework.integration.errorLogger
2015-04-08 10:44:09.370  INFO 11548 --- [       Thread-1] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase -2147483648
2015-04-08 10:44:09.373  INFO 11548 --- [       Thread-1] o.s.s.c.ThreadPoolTaskScheduler          : Shutting down ExecutorService 'taskScheduler'

Conclusion

This has been a very simple Hello World example using Spring Integration. While this post only scratches the surface of the abilities of Spring Integration, I hope you can see how easy it is to utilize Spring Integration in your code. As you learn to develop large scale enterprise applications, you will find that Spring Integration is an important module in the Spring Framework.

Get The Code

I’ve committed the source code for this post to github. It is a Maven project which you can download and build. If you wish to learn more about the Spring Framework, I am a free introduction to Spring tutorial. You can sign up for this tutorial in the section below.

Source Code

The source code for this post is available on github. You can download it here.

About jt

    You May Also Like