Spring Integration Basics
Spring integration supports enterprise integration patterns. Its basically light weight messaging system with spring application to connect with other external systems. Spring Integration’s primary goal is to provide a simple model for building enterprise integration solutions while maintaining the separation of concerns that is essential for producing maintainable, testable code.
It is based on same Spring concepts of DI and POJOs. It provides a way of sharing information quickly and with a high level of decoupling between involved components or applications.
Spring integration is a big wrapper on messaging system as you don’t write code to create channel but follows spring declarative approach.
Addressed concern in enterprise applications:
1. Communication between components in application using in-memory messaging. Loose coupling achieved by sharing data using message channels.
2. It allows communication with external systems. You just need to send the information; Spring Integration will handle sending it to the specified external system and bring back a response if necessary. Of course, this works the other way round; Spring Integration will handle incoming calls from the external system to your application.
Spring Integration API is very simple with 3 components in it:
1. Message is sent to an endpoint.
2.Endpoints are connected through message channels.
3. Endpoint can receive messages from message channels.
Message: Message will have header and payload. Header is basically key value pair.
Message channels: It is of 2 types, Direct and publish-subscribe.
Endpoints: Endpoints are similar to the controller defined in Spring MVC. Like in controller paths are defined and then controller takes care of what to do with incoming request which matches the path. Same way endpoints decides what to do with incoming data. Below is a list of different types of endpoints available.
- Channel adapter: Connects the application to an external system (unidirectional)
- Gateway: Connects the application to an external system (bidirectional)
- Service Activator: Can invoke an operation on a service object.
- Transformer: Converts the content of a message.
- Filter: Determines if a message can continue its way to the output channel.
- Router: Decides to which channel the message will be sent.
- Splitter: Splits the message in several parts.
- Aggregator: Combines several messages into a single one.
Implementation Example
To explain how to use spring integration I am taking the example of file transfer.
1. Spring configuration in XML
We got to have XML configuration placed at src/resources/META-INF.spring.integration folder.
Here is the sample:
<file:inbound-channel-adapter id="filesIn"
directory="file:${java.io.tmpdir}/spring-integration-samples/input"
filename-regex="[a-z]+.txt">
<integration:poller id="poller" fixed-delay="5000"/>
</file:inbound-channel-adapter>
<file:file-to-string-transformer input-channel="filesIn" output-channel="strings"/>
<integration:channel id="strings"/>
<integration:service-activator input-channel="strings"
output-channel="filesOut"
ref="handler"/>
<file:outbound-channel-adapter id="filesOut" directory="file:${java.io.tmpdir}/spring-integration-samples/output"/>
<bean id="handler" class="org.springframework.integration.samples.filecopy.Handler"/>
Summary of whole XML.
1. I need an input channel adaptor which will take files from specified directory, and it will poll for every 5 sec.
2. Need string transformer which takes contents from input channel and flush the output to output channel.
3. Use service activator which takes inout from input channel process it and write output in output-channel.
4. Need outbound channel adapter which writes files in specified directory.
Defining Handler:
public class Handler {
public String handleString(String input) {
System.out.println("Copying text: " + input);
return input.toUpperCase();
}
}
Thats all you need to write in spring integration.
Sample code for testing
public static void main(String[] args) throws Exception{
ApplicationContext context = new ClassPathXmlApplicationContext("/META-INF/spring/integration/fileCopyDemo-text.xml", FileCopyDemoCommon.class);
File inDir = (File) new DirectFieldAccessor(context.getBean(FileReadingMessageSource.class)).getPropertyValue("directory");
LiteralExpression expression = (LiteralExpression) new DirectFieldAccessor(context.getBean(FileWritingMessageHandler.class)).getPropertyValue("destinationDirectoryExpression");
File outDir = new File(expression.getValue());
System.out.println("Input directory is: " + inDir.getAbsolutePath());
System.out.println("Output directory is: " + outDir.getAbsolutePath());
System.out.println("===================================================");
Thread.sleep(3000);
((ClassPathXmlApplicationContext) context).close();
}