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

问题描述 投票:2回答:1

当给定评估返回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解决方案似乎可以正常工作,它与上面的过滤器实现之间是否真的有任何收益?

spring spring-boot spring-integration spring-integration-dsl
1个回答
1
投票

嗯,这实际上与Java DSL方法以及如何使用它们无关。这实际上是关于这些IE模式的理论。

让我们比较EIP中的FilterRecipientListRouter

过滤器-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确实看起来像是[[基于内容的路由器 :-)的特定实现。

© www.soinside.com 2019 - 2024. All rights reserved.