当给定评估返回false时,我需要将消息从父流程路由到新流程,但当该评估返回true时,请在父流程中继续传递消息。目前,我已经能够使用Spring Integration DSL .filter()
方法成功实现此功能,而没有任何问题。但是,我觉得以这种方式使用.filter()
并不属于这种方法的真实意图。是否有某种类型的路由器可以用来更好地满足这一需求?是否有必要从此.filter()
实现更改为基于路由器的实现?
以下面的集成流程配置为例...
@Bean
public IntegrationFlow flow() {
return IntegrationFlows
.from("inboundChannel")
.filter(someService::someTrueFalseMethod, onFalseReturn -> onFalseReturn.discardChannel("otherFlowInboundChannel"))
.handle(someService::someHandleMethod)
.get();
}
@Bean
public IntegrationFlow otherFlow() {
return IntegrationFlows
.from("otherFlowInboundChannel")
.handle(someOtherService::someOtherHandleMethod)
.get();
}
到目前为止,看来.routeToRecipents()
可能是我需要使用的。在我的场景中,我需要评估消息的标题,因此才使用recipientMessageSelector
。
@Bean
public IntegrationFlow flow() {
return IntegrationFlows
.from("inboundChannel"
.routeToRecipients(router -> router
.recipientMessageSelector("otherFlowInboundChannel", someService::someTrueFalseMethod)
.defaultOutputToParentFlow()
)
.handle(someService::someHandleMethod)
.get();
}
@Bean
public IntegrationFlow otherFlow() {
return IntegrationFlows
.from("otherFlowInboundChannel")
.handle(someOtherService::someOtherHandleMethod)
.get();
}
即使此routeToRecipients
解决方案似乎可以正常工作,它与上面的过滤器实现之间是否真的有任何收益?
嗯,这实际上与Java DSL方法以及如何使用它们无关。这实际上是关于这些IE模式的理论。
让我们比较EIP中的Filter
和RecipientListRouter
!
过滤器-https://www.enterpriseintegrationpatterns.com/patterns/messaging/Filter.html:
如果消息内容符合消息过滤器指定的条件,则消息将路由到输出通道。如果消息内容不符合条件,则将消息丢弃。
所以,从技术上讲filter
与您的期望不符,因为在false
分辨率上,您有点discard消息。但是,为了对那些丢弃的消息进行可能的处理,Spring Integration提供了discardChannel
选项来启动丢弃子流。因此,我们可以将其视为if..else
构造...
收件人列表-https://www.enterpriseintegrationpatterns.com/patterns/messaging/RecipientList.html
然后使用收件人列表检查传入的邮件,确定所需收件人的列表,并将该邮件转发到与列表中的收件人关联的所有渠道。
所以,还需要什么,因为您先评估一条消息和该消息的收件人,然后再发送到他们的频道。仅此问题会模拟filter
行为,因为您将不会拥有两个以上具有互斥目的的通道。
[当filter
方法感觉像流控制滥用时(提醒我Java中类似的逻辑依赖于流控制的异常处理),它并不指示我们要始终遵循规范行为以导致错误结束当消息不符合条件时。
recipientList
适用于更复杂的场景,其中选择器用于任意评估,而不仅仅是简单的布尔值,并且具有将同一条消息分发到多个输出通道的能力。因此,对于这种简单的true/false
场景,我不推荐使用它。
您可能考虑研究另一种相似的模式:
基于内容的路由器-https://www.enterpriseintegrationpatterns.com/patterns/messaging/ContentBasedRouter.html
使用基于内容的路由器根据邮件内容将每个邮件路由到正确的收件人。
[这个感觉非常接近true/false
所需要的东西,它不会滥用流量控制的错误(丢弃),也不会给我们指定收件人列表。当您要依赖于非映射结果时,它也具有defaultOutputToParentFlow()
。
恕我直言,我会留在filter()
上-它的true/false
逻辑和discardChannel
确实看起来像是[[基于内容的路由器 :-)的特定实现。