Routing
A flow can end by handing its Exchange on to other flows or channels chosen at runtime, instead of
a fixed toSink(…). Two constructs do this: toRoute(…), which picks destinations with
expressions, and toRecipientList(…), which is deprecated.
Expression-based routing
toRoute(…) evaluates a list of expressions in order and sends the message to the destinations of
the first one that is true.
.toRoute(route -> route.dynamic()
.when("Headers['type'] == 'PAYMENT'").then("queue://payment-flow") (1)
.when("Headers['type'] == 'REFUND'").then("queue://refund-flow", "slf4j://audit") (2)
.otherwise("queue://default-flow") (3)
.end() (4)
)
| 1 | .when(expression) is a boolean expression (see Expressions) and .then(…) the destination reached when it is true. |
| 2 | .then(…) accepts several destinations: the message is sent to all of them, each receiving its own copy of the Exchange. |
| 3 | .otherwise(…) is the fallback when no expression is true. Without it, a message that matches nothing fails like a failed step, and is handled by the flow’s error handling. |
| 4 | .end() closes the routing table. |
A destination is a URL: queue://<queue name> reaches an internal flow (the queue its fromSource("queue://…") reads), any other channel adapter protocol reaches an external system. A bare name is rejected when the flow is defined.
Destinations computed per message
A destination may contain a #{…} expression, evaluated against each message with Payload and Headers available:
.toRoute(route -> route.dynamic()
.when("Payload != null").then("queue://#{Headers['region']}-orders")
.end()
)
#{…} is resolved for each message when it is routed. The ${…} property placeholders of the Spring integration are not resolved in routing destinations - see Endpoint URL Property Placeholders.
|
Recipient List
The Recipient List pattern sends the message to several destinations at once.
For a fixed set of destinations, or a set chosen by an expression, toRoute(…) above already does this: pass several destinations to .then(…).
The dedicated toRecipientList(…) construct is deprecated:
.toRecipientList(list -> list
.toRecipients("queue://flow-a", "queue://flow-b") (1)
.when("Headers['audit'] == 'true'").toRecipient("slf4j://audit-logger") (2)
.end())
| 1 | Recipients that always receive the message. |
| 2 | A recipient added only when the expression is true. |
Prefer toRoute(route → route.dynamic()…) for new flows.