,

Using Spring Integration Futures

This past week I had a real world use case for using Spring Integration Futures. I was looking into optimizing the checkout experience for a large ecommerce website. Consider what happens in a large scale website when an order is submitted. Typically, you will see a process something like:

  • Validate the place order form information
  • Verify the address against an address service
  • Verify the credit card with a payment processor
  • Verify available inventory

Each of these in a large scale enterprise are services. For example, it is common for an enterprise to subscribe to an address validation service. This helps ensure shipping accuracy. Or you’ll have a inventory service to help manage inventory levels. Normally not a problem. But when you have a black friday shopping special and thousands of users shopping on the site, managing inventory can become tricky.

Each of these services will take some time to execute. If called in sequence, the website response time slows down and impacts the user experience in the checkout flow. However, in my example here, there is no reason these service calls couldn’t be called concurrently. By calling the services concurrently, the response time now is the longest service call, not the sum of all the service calls. If each service call takes a half second, calling the services sequentially would take 2 seconds of elapsed time. Calling them concurrently only takes a half second.

A couple weeks back I wrote a blog post on testing Spring Integration Gateways.  In this use case, Spring Integration is the perfect tool. Spring Integration has a very cool feature to support asynchronous calls. When using Spring Integration Messaging Gateways, if you wrap the return time in a Java Future, Spring Integration will automatically handle the request in a different thread using a thread pool. As an application developer, this makes writing a multithreaded application very easy to do. The Spring Framework and Spring Integration handle the complexity of managing the worker threads and the thread pool.

In this post, I’m going to walk you through the configuration of the Spring Integration gateways and Spring service beans used to make these four service calls supporting my ecommerce place order example.

Spring Integration Code Examples

Command Objects

In this example, I’m going to use a command object. In a web application, this would typically have values bound to it from a form post. However, in today’s omni-channel retail environment, the website is not the only client I need to worry about. This request could be coming from a native iOS mobile application, a native Android mobile application, an in-store kiosk, or maybe a stand alone customer service application.

By using a command object, I’m decoupling my processing from the front end client. I don’t care where the request originated. Maybe it was a form post. Maybe a web service, could be a JMS request. It doesn’t really matter where the request originated.

Place Order Command

Domain Objects

For this example, I’ve created a couple domain objects. These are just simple POJOs I’m using to illustrate the example. In a real application these objects would be much more robust. 

Order

OrderLine

Product

Spring Integration Gateways

For this example, I’ve defined four different Spring Integration Messaging Gateways. Technically, I could have used just one Spring Integration Messaging Gateway, but that would have been a violation of the Single Responsibility Principle. This approach does lead to more class files. But when I need to maintain this code, I know where to look. The programming logic is clear and organized.

OrderGateway

The Order Gateway interface defines two methods. The first placeOrder  is the start of our processing chain.  This is where we will submit the command object. The second method is used in our the processing of the place order command object.

Note: notice the usage of the Java Future  for the return time of the validateOrder method. This is what instructs Spring Integration to perform the method call asynchronously using a thread pool.

AddressGateway

InventoryGateway

PaymentGateway

Spring Services

Since this is a Spring project, we’ll create our services as Spring Beans, and naturally will we be using Dependency Injection and program to an interface.

OrderService

OrderServiceImpl

The implementation of our Order Service is one of the more complex classes in this tutorial. You can see we are having Spring autowire our four Spring Integration Messaging Gateways into the class. In the placeOrderMethod , you can see I call a method on each of the four Spring Integration Gateways. Each method returns a Java Future. After all four are submitted, I go back to get the value of the Future. In this case, I’m using the Spring Errors object. If all four validation steps come back without errors, in a real system I’d persist the order to the database and do any post processing. But this is just a little sample to show off the use of Spring Integration Futures. So in this case, I’m just returning the command object either way.

Spring Integration Configuration

I had to expand on the Spring Integration configuration from our previous example. You’ll see I’m using the Spring Integration Gateway tag to define the four Spring Integration Gateways we’re using. Then I defined the Spring Integration channels and the appropriate Spring Integration service activators. Nothing new here over the previous example. Just a little more routing to take care of.

Notice how I did not define a thread pool? By default, Spring Integration is providing a thread pool for our use. You can of course define your own or update the settings of the default thread pool if needed.

si-config.xml

Running the Spring Integration Code

I’ve setup a Spock test to run the Spring Integration code in this example. 

OrderGatewayTests

When you run this Spock test you will see the following output:

Each the services I’ve wired into this example do simple print line statements out to the console. Each starts their respective output with the Id number of the thread they are running in. You can see from the output how each service is running concurrently in different threads.

Conclusion

As a programmer, Spring Integration is a very powerful tool to have in your toolbelt. You can see from this example how I’ve created a multithreaded application with a minimal amount of coding. I simply wrapped the return type I wanted on the Spring Integration Messaging Gateways with a Java Future. Spring Integration and Spring managed the thread pool for me. I didn’t need to worry about managing threads. The Spring Framework allowed me to focus on delivering the business solution, and took care of the complex boiler plate code.

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 have 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.

  • 1.8

    Overall Score

  • Reader Rating: 4 Votes

Share

You May Also Like

One comment

  1. Nice article, thanks for sharing.

Leave a Reply