Introducing Spring Integration

In this article we introduce Spring Integration. If you have not worked with Spring Integration before, it might help to brush up on Enterprise Integration Patterns by Gregor Hohpe. Also I will recommend this excellent introductory article by Josh Long.

Context setting

In a nutshell, Enterprise Integration Patterns is all about how to get two application (possibly on different technology stacks, different machines, different networks) talk to each other, in order to provide a single business functionality. The challenge is how to ensure that this communication remains transparent to business user, yet reliable and easy for applications. Messaging is one of the patterns. Using this pattern applications can talk to each other frequently, immediately, reliably, and asynchronously, using customizable formats. Applications talk to each other by sending data (called Messages) over virtual pipes (called Channels). This is overly simplistic introduction to the concept, but hopefully enough to make sense of the rest of the article.

Spring Integration is not an implementation of any of the patterns, but it supports these patterns, primarily Messaging.

The rest of this article is pretty hands on and is an extension of the series on Spring 3. The earlier articles of this series were:

  1. Hello World with Spring 3 MVC
  2. Handling Forms with Spring 3 MVC
  3. Unit testing and Logging with Spring 3
  4. Handling Form Validation with Spring 3 MVC

Without further ado, let’s get started.

Bare bones Spring Integration example

At the time of writing this article the latest version of Spring is 3.1.2.RELEASE. However, the latest version of Spring Integration is 2.1.3.RELEASE, as found in Maven Central. I was slightly – and in retrospect, illogically – taken aback that the Spring and Spring Integration should have different latest versions, but, hey that’s how it is. This means our pom.xml should have an addition now (if you are wondering where did that come from you need to follow through, at least on a very high level, the Spring 3 series that I have mentioned earlier in the article).

File: /pom.xml

<!-- Spring integration -->                           
<dependency>                                          
 <groupId>org.springframework.integration</groupId>
 <artifactId>spring-integration-core</artifactId>  
 <version>2.1.3.RELEASE</version>                  
</dependency>                                          

This one dependency in the pom, now allows my application to send message over channels. Notice that now we are referring to message and channels in the realm of Spring Integration, which is not necessarily exactly same as the same concepts referred earlier in this article in the realm of Enterprise Integration Patterns. It is probably worth having a quick look at the Spring Integration Reference Manual at this point. However, if you are just getting started with Spring Integration, you are perhaps better off following this article for the moment. I would recommend you get your hands dirty before returning to reference manual, which is very good but also very exhaustive and hence could be overwhelming for a beginner.

To keep things simple, and since I generally try to do test first approach (wherever possible), let us try and write some unit tests to create message, send it over a channel and then receive it. I have blogged here about how to use JUnit and Logback in Spring 3 applications. Continuing with the same principle, assuming that we are going to write a HelloWorldTest.java, let’s set up the Spring configuration for the test.

File: \src\test\resources\org\academy\integration\HelloWorldTest-context.xml

<?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:p='http://www.springframework.org/schema/p' 
 xmlns:int='http://www.springframework.org/schema/integration' 
 xsi:schemaLocation='http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd


http://www.springframework.org/schema/integration


http://www.springframework.org/schema/integration/spring-integration-2.1.xsd'>

 <int:channel id='inputChannel'></int:channel>

 <int:channel id='outputChannel'>
  <int:queue capacity='10' />
 </int:channel>

 <int:service-activator input-channel='inputChannel'
  output-channel='outputChannel' ref='helloService' method='greet' />

 <bean id='helloService'
  class='org.academy.integration.HelloWorld' /> 

</beans>

So, what did we just do? We have asked Spring Integration to create a ‘inputChannel’ to send messages to. A ‘outputChannel’ to read messages from. We have also configured for all messages on ‘inputChannel’ to be handed over to a ‘helloService’. This ‘helloService’ is an instance of org.academy.integration.HelloWorld class, which should be equipped to do something to the message. After that we have also configured that the output of the ‘helloService’ i.e. the modified message in this case to be handed over to the ‘outputChannel’. Simple, isn’t it? Frankly, when I had a worked with Spring Integration a few years ago for the first time, I found this all a bit confusing. It does not make much sense to me till I see this working. So, let’s keep going. Let’s add our business critical HelloWorld class.

File: /src/main/java/org/academy/integration/HelloWorld.java

package org.academy.integration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
 private final static Logger logger = LoggerFactory
   .getLogger(HelloWorld.class);
 
 public String greet(String name){
  logger.debug('Greeting {}', name); 
  return 'Hello ' + name; 
 }
}

As, you can see, given a ‘name’ it return ‘Hello {name}’. Now, let’s add the unit test to actually put this in action.

File: /src/test/java/org/academy/integration/HelloWorldTest.java

package org.academy.integration;

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.message.GenericMessage;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class HelloWorldTest {
 private final static Logger logger = LoggerFactory
   .getLogger(HelloWorldTest.class);

 @Autowired
 @Qualifier('inputChannel')
 MessageChannel inputChannel;

 @Autowired
 @Qualifier('outputChannel')
 PollableChannel outputChannel;

 @Test
 public void test() {
  inputChannel.send(new GenericMessage<String>('World'));
  assertEquals(outputChannel.receive().getPayload(), 'Hello World');
  logger.debug('Checked basic Hello World with Spring Integration');
 }

}

Although not mandatory, I find it easier to use the following logback setting. Feel free to use it, if you fancy.

File: /src/main/resources/logback.xml

<?xml version='1.0' encoding='UTF-8'?>
<configuration>
 <appender name='CONSOLE' class='ch.qos.logback.core.ConsoleAppender'>
  <encoder>
   <pattern>%d %5p | %t | %-55logger{55} | %m %n</pattern>
  </encoder>
 </appender>

 <logger name='org.springframework'>
  <level value='ERROR' />
  <!-- level value='INFO' />  -->
  <!--  level value='DEBUG' />  -->
 </logger>

 <root>
  <level value='DEBUG' />
  <appender-ref ref='CONSOLE' />
 </root>
</configuration>

Now, simply type ‘mvn -e clean install’ (or use m2e plugin) and you should be able to run the unit test and confirm that given string ‘World’ the HelloWorld service indeed returns ‘Hello World’ over the entire arrangement of channels and messages.

Again, something optional but I highly recommend, is to run ‘mvn -e clean install site’. This – assuming you have correctly configured some code coverage tool (cobertura in my case) will give you a nice HTML report showing the code coverage. In this case it would be 100%. I have blogged a series on code quality which deals this subject in more detail, but to cut long story short, it is very important for me to ensure that whatever coding practice / framework I use and recommend use, complies to some basic code quality standards. Being able to unit test and measure that is one such fundamental check that I do. Needless to say, Spring in general (including Spring integration) passes that check with flying colours.

Conclusion

That’s it for this article. In the next article, we will see how to insulate the application code from the Spring Integration specific code that we have in our current JUnit test i.e. inputChannel.send(…) etc. Till then, happy coding.

Suggested further reading …
Here are the links to earlier articles in this series:

  1. Hello World with Spring 3 MVC
  2. Handling Forms with Spring 3 MVC
  3. Unit testing and Logging with Spring 3
  4. Handling Form Validation with Spring 3 MVC

These are excellent material that I can recommend:

  1. Getting started with Spring Integration
  2. Sample codes with Spring Integration
  3. Spring Integration – Session 1 – Hello World
  4. Spring Integration – Session 2 – More Hello Worlds

Continue to Spring Integration with Gateways

Reference: Introducing Spring Integration from our JCG partner Partho at the Tech for Enterprise blog.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

One Response to "Introducing Spring Integration"

  1. Vijay says:

    Very nice example. I know this is old article, but very easy to understand the basics.

Leave a Reply


− 1 = six



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books