A quick question on SPEL syntax in Spring Integration.
In the following code sample, what's the correct way to access myMember
within a SPEL expression?
@Component
@RequiredArgsConstructor //Lombok
public class MyClass(
// autowired member
private final MyMember myMember;
@Bean
public IntegrationFlow myFlow() {
return IntegrationFlows
.from(...)
.routeToRecipients(
r -> r.ignoreSendFailures(false)
.recipientFlow(...)
// #this and #root both refer to the message and give access
// to payload and headers, but can I also access myMember
// in this SPEL expression?
.recipientFlow("@#?...myMember.method(...)", // returns true or false
subflow())
)
...
.get();
}
I can of course easily work this around by setting a header with the results of myMember.method(...) beforehand, but I was wondering if I could use a shortcut.
The reference documentation gives a few examples of recipient methods to use in the RecipientListRouterSpec
parameter of the routeToRecipients
method:
@Bean
public IntegrationFlow recipientListFlow() {
return IntegrationFlows.from("recipientListInput")
.<String, String>transform(p -> p.replaceFirst("Payload", ""))
.routeToRecipients(r -> r
.recipient("thing1-channel", "'thing1' == payload")
.recipientMessageSelector("thing2-channel", m ->
m.getHeaders().containsKey("recipient")
&& (boolean) m.getHeaders().get("recipient"))
.recipientFlow("'thing1' == payload or 'thing2' == payload or 'thing3' == payload",
f -> f.<String, String>transform(String::toUpperCase)
.channel(c -> c.queue("recipientListSubFlow1Result")))
.recipientFlow((String p) -> p.startsWith("thing3"),
f -> f.transform("Hello "::concat)
.channel(c -> c.queue("recipientListSubFlow2Result")))
.recipientFlow(new FunctionExpression<Message<?>>(m ->
"thing3".equals(m.getPayload())),
f -> f.channel(c -> c.queue("recipientListSubFlow3Result")))
.defaultOutputToParentFlow())
.get();
}
The last example of the recipientFlow
methods above is the one that takes an Expression and an IntegrationFlow as parameters. This integration flow is invoked only if the expression evaluates to true
.
A FunctionExpression can be used to solve the OP:
@Component
@RequiredArgsConstructor //Lombok
public class MyClass(
// autowired member
private final MyMember myMember;
@Bean
public IntegrationFlow myFlow() {
return IntegrationFlows
.from(...)
.routeToRecipients(
r -> r.ignoreSendFailures(false)
.recipientFlow(...)
.recipientFlow(new FunctionExpression<Message<?>>(
m -> myMember.method(...), // returns true or false
subflow())
)
...
.get();
}