Message Driven Microservices with Spring Cloud Stream and RabbitMQ (Publish and Subscribe messages) – using @StreamListener for header based routing – Part 3

In this article, i am not going to explain the basics of Spring Cloud Stream OR the process of creating publishers and subscribers.  Those have been clearly described in the Part 1 and Part 2 of this article series.

It is possible to send messages with headers. In the receiving end (consumer application), there can be multiple message handlers (@StreamListener annotated methods) those accepts messages based on the headers of the message.

A copy of the message will be sent to every handler method and they will accept the message if it matches the given condition . The condition is a SpEL expression (Spring Expression Language) that performs checks on header values.  The sample condition is given as follows.


@StreamListener(target = OrderSink.INPUT,condition = "headers['payment_mode']=='credit'")

(Please refer the source code the complete code)

In that way, you can use the headers to route messages (message routing) among multiple message handlers.  Here we will look at, how to deliver the messages to the correct recipient based on the header.

Setting up the publisher application

The development of publisher application is almost similar to previous article (part 2) except the OrderController used in message publishing.  The messages will be published with header(s) and those headers will be used in the consumer application for directing the message to the correct handler.

Please refer the below OrderController class.

public class OrderController
private OrderSource source;
public String publishOrder(@RequestBody Order order, @RequestParam("payment_mode") String paymentMode)
return "order_published";


As you can see that, the message will be published with a header known as “payment_mode” . The user will send the payment_mode as a request parameter and the controller method will set it as a message header when building the message.


Setting up the consumer application

The development of  consumer application is also similar to the previous article except the OrderListener used in message receiving.

OrderListener will have set of message handlers for receiving messages based on SpEL condition (or rather header values)

Please refer the below OrderListener class.

public class OrderListener
@StreamListener(target = OrderSink.INPUT,condition = "headers['payment_mode']=='cash'")
public void listenForCashOrder(Order order)
{" received new CASH order {} ",order.toString());
@StreamListener(target = OrderSink.INPUT,condition = "headers['payment_mode']=='credit'")
public void listenForCreditOrder(Order order)
{" received new CREDIT order {} ",order.toString());
@StreamListener(target = OrderSink.INPUT,condition = "headers['payment_mode']=='cheque'")
public void listenForChequeOrder(Order order)
{" received new CHEQUE order {} ",order.toString());


As you can see that, there are three handler methods with different acceptance conditions based on header called “payment_mode“.


Testing and Running 

Lets publish few messages as follows. Then we will check wether they are directed to the correct handler based on the message header.


Lets publish a message with by setting the request param “payment_mode” as cash

Screen Shot 2018-07-30 at 9.45.07 PM.png



Lets publish a message with by setting the request param “payment_mode” as credit

Screen Shot 2018-07-30 at 9.45.19 PM.png



Lets publish a message with by setting the request param “payment_mode” as cheque

Screen Shot 2018-07-30 at 9.45.32 PM.png



Now, the consumer application should receive Cash, Credit and Cheque messages in respective handlers (as the published order).  Please refer the below log segment of the consumer.

Screen Shot 2018-07-30 at 9.45.50 PM.png


The Source Code

The complete source code of this article has been added to the GitHub.  Click here to download.

If you have any query or clarification, please feel free to drop a message.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s