Spring 集成 DSL 过滤器与带有单个收件人和 DefaultOutputToParentFlow 的 RouteToRecipients

Spring Integration DSL Filter vs. RouteToRecipients w/ single Recipient and DefaultOutputToParentFlow

当给定评估 returns 为假时,我需要将消息从我的 parent 流程路由到新流程,但当该评估 parent 流程 returns 是的。目前,我已经能够使用 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() 可能是我需要使用的。在我的场景中,我需要评估消息的 headers,这就是使用 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 中的 FilterRecipientListRouter

过滤器 - https://www.enterpriseintegrationpatterns.com/patterns/messaging/Filter.html:

If the message content matches the criteria specified by the Message Filter, the message is routed to the output channel. If the message content does not match the criteria, the message is discarded.

因此,技术上 filter 不符合您的期望,因为在 false 决议中您有点 丢弃 消息。但是,为了可能对那些丢弃的消息进行处理 Spring,集成提供了一个 discardChannel 选项来启动丢弃子流。所以,我们可以把它当作if..else构造...

收件人列表 - https://www.enterpriseintegrationpatterns.com/patterns/messaging/RecipientList.html

Then use a Recipient List to inspect an incoming message, determine the list of desired recipients, and forward the message to all channels associated with the recipients in the list.

所以,这有点像您所需要的,因为您评估了一条消息及其收件人,然后将其发送到他们的频道。唯一的问题是模拟 filter 行为,因为您不会有两个以上的通道具有相互排斥的目的。

filter 方法感觉像是滥用流量控制时(让我想起 Java 中的类似逻辑依赖于流量控制的异常处理),它并不要求我们继续使用当消息不符合条件时,总是以错误结束的规范行为。

The recipientList is for more complicated scenarios when a selector is used for any arbitrary evaluation, not just plain boolean and has an ability to distribute the same message into several output channels.因此,我不建议将它用于这种简单的 true/false 场景。

您可以考虑研究另一个类似的模式:

基于内容的路由器 - https://www.enterpriseintegrationpatterns.com/patterns/messaging/ContentBasedRouter.html

Use a Content-Based Router to route each message to the correct recipient based on message content.

这个感觉非常接近您对 true/false 的需求,它不会滥用错误(丢弃)进行流量控制,也不会要求我们提供收件人列表。当您想依赖非映射结果时,这个也有 defaultOutputToParentFlow()

恕我直言,我会继续使用 filter() - 其 true/false 逻辑和 discardChannel 它看起来确实像是 Content Based Router[=61] 的特定实现=] :-).