如何等待多线程发布 - 订阅 - 频道的完成

时间:2013-02-27 14:18:18

标签: java spring-integration

我有一个Spring Integration项目,我希望通过多个操作同时处理消息。所以我设置了publish-subscribe-channel task-executor。但是我想在继续之前等待所有处理完成。我该怎么做?

<publish-subscribe-channel id="myPubSub" task-executor="my10ThreadPool"/>

<channel id="myOutputChannel"/>

<service-activator input-channel="myPubSub" output-channel="myOutputChannel"
         ref="beanA" method="blah"/>
<service-activator input-channel="myPubSub" output-channel="myOutputChannel"
         ref="beanB" method="blah"/>

<service-activator id="afterThreadingProcessor" input-channel="myOutputChannel" .../>

因此,在上述情况下,我希望在afterThreadingProcessorbeanA完成工作后,我只需要调用beanB一次。但是,在上面afterThreadingProcessor将被调用两次。

2 个答案:

答案 0 :(得分:4)

  1. apply-sequence="true"添加到pub-sub频道(这会将默认关联数据添加到邮件中,包括correlationIdsequenceSizesequenceNumber,并允许默认下游组件使用的策略)。

  2. <aggregator/>之前添加afterThreadingProcessor,并将两个<service-activator/>的输出路由到它。

  3. 在聚合器后添加<splitter/> - 默认拆分器会将聚合器生成的集合拆分为两条消息。

  4. 对于完成其工作的第二个线程上的每条消息,将调用

    afterThreadingProcessor

    您可以使用链...

    使配置更容易
    <chain input-channel="myOutputChannel">
        <aggregator />
        <splitter />
        <service-activator id="afterThreadingProcessor" input-channel="myOutputChannel" .../>
    </chain>
    

    要拨打最终服务,只需更改您的服务即可Collection<?>而不是添加拆分器。

    编辑:

    为了在评论#3中做你想做的事情(在原始线程上运行最终服务),这应该有用......

    <int:channel id="foo" />
    <int:service-activator ref="twoServicesGateway" input-channel="foo"
          output-channel="myOutputChannel" />
    
    <int:gateway id="twoServicesGateway" default-request-channel="myPubSub"/>
        <int:publish-subscribe-channel id="myPubSub" task-executor="my10ThreadPool"
                apply-sequence="true"/>
        <int:service-activator input-channel="myPubSub" output-channel="aggregatorChannel"
             ref="beanA" method="blah"/>
        <int:service-activator input-channel="myPubSub" output-channel="aggregatorChannel"
             ref="beanB" method="blah"/>
        <int:aggregator input-channel="aggregatorChannel" />
    
    <int:service-activator id="afterThreadingProcessor" input-channel="myOutputChannel" .../>
    

    在这种情况下,网关封装了其他两个服务和聚合器;默认service-interface是一个简单的RequestReplyExchanger。调用线程将等待输出。由于聚合器没有output-channel,框架会将回复发送到网关,等待线程将接收它,返回<service-activator/>,结果将被发送到最终服务。

    您可能希望在网关上放置一个reply-timeout,因为默认情况下它将无限期地等待,如果其中一个服务返回null,则不会收到任何agreggated响应。

    请注意,我缩进网关流只是为了显示它从网关运行,它们不是网关的子元素。

答案 1 :(得分:0)

现在可以使用 Spring Integration 4.1.0 中引入的更清晰的方法来实现相同类型的行为,作为EIP Scatter的实现 - 收集 模式。

Checkout Scatter-Gather示例要点: https://gist.github.com/noorulhaq/b13a19b9054941985109