Get ahead
VMware offers training and certification to turbo-charge your progress.
Learn moreAfter my talk on Spring Integration I've been getting quite some questions on clarification and samples. To meet the demand I will start a small series on implementing different integration patterns using Spring Integration. This first article will focus on the basics. It will show you how to get up and running and walk through one of the samples.
If you never heard about Spring Integration before it might be a good idea to familiarize yourself with it reading the introductory blog Mark Fisher wrote about it or by browsing the project website. In general
Let me start with a disclaimer: the patterns you're about to see here are merely meant as an illustration to the features that Spring Integration has to offer; syntax may vary through different versions and extra precautions might be needed on your system.
The first step to getting involved in Spring Integration is to download the project and look at the sample. So let's start with that:
In the cafe package of the sample project you will find all the code related to the implementation of the famous Starbucks story. To introduce you to the architecture I will follow an order from start (Cafe) to finish (Barista):
First the order is created by CafeDemo. It contains two drinks, one hot, one cold. Then the order is wrapped in a message and put on the 'orders' channel. The endpoint listening to the 'orders' channel is a splitter (OrderSplitter) in the split method the order is split up into multiple Drinks which are in turn wrapped into separate messages by the framework.
After being split and put on the 'drinks' channel the drinks are being processed by the DrinksRouter. This router has the responsibility of putting hot drinks on the 'hotDrinks' channel and cold drinks on the 'coldDrinks' channel. Both these channels are handled by different endpoints that use the prepareHotDrink and preprareColdDrink method on the Barista respectively.
Let's follow the flow of messages through the relevant bits of code:
In the cafeDemo.xml bean definition file you can see a Cafe being configured as a bean.
<beans:bean id="cafe"
class="org.springframework.integration.samples.cafe.Cafe">
<beans:property name="orderChannel" ref="orders" />
</beans:bean>
This bean is used by the CafeDemo main method to put order messages on the order queue.
Cafe cafe = (Cafe) context.getBean("cafe");
DrinkOrder order = new DrinkOrder();
Drink hotDoubleLatte = new Drink(DrinkType.LATTE, 2, false);
Drink icedTripleMocha = new Drink(DrinkType.MOCHA, 3, true);
order.addDrink(hotDoubleLatte);
order.addDrink(icedTripleMocha);
for (int i = 0; i < 100; i++) {
cafe.placeOrder(order);
}
A <context:component-scan ...../> is being used in cafeDemo.xml to bootstrap the OrderSplitter and DrinkRouter.
The OrderSplitter is sprinkled with some annotations:
@MessageEndpoint(input="orders", output="drinks")
public class OrderSplitter {
@Splitter
public List<Drink> split(Message<DrinkOrder> orderMessage) {
return orderMessage.getPayload().getDrinks();
}
}
The DrinkRouter is similarly decorated with annotations that tell Spring Integration to use it as a router. The string returned from the @Router annotated method is interpreted by Spring Integration as the output channel.
@MessageEndpoint(input="drinks")
public class DrinkRouter {
@Router
public String resolveDrinkChannel(Drink drink) {
return (drink.isIced()) ? "coldDrinks" : "hotDrinks";
}
}
After the routing the messages are available on the hotDrinks or coldDrinks channel depending on their temperature.
The endpoints configured to call the appropriate method on the Barista are configured in xml:
You can see that both the input channel and the method to feed the message to are defined so Spring Integration knows what to do.
Notice that you don't need to unwrap the message yourself: accepting the payload type as input parameter is fine as well. If you change the methods in the Barista to accept Message public void prepareColdDrink(Message
Play around with the sample and post on the forum if you have any troubles. You'll find that they are quite helpful already (mainly because Mark responds to almost every post). Next episode will feature an other implementation of an EIP.