Spring集成流程:在流程中执行任务

时间:2016-02-10 16:42:19

标签: java spring spring-integration dsl

希望这是我提出的关于Spring集成的最后一个问题。

面临以下问题:在相当长的IntegrationFlow dsl表的末尾有一个代码:

   return IntegrationFlows.
   //...
       .enrichHeaders(headerEnricherSpec -> headerEnricherSpec.header("jms_replyTo", responseQueue(), true)) // IntegrationMessageHeaderAccessor.CORRELATION_ID is not acceptable though message came from outgoingGateway of another application with this header been set
       .handle(requestRepository::save)
       .handle(
            Jms.outboundAdapter(queueConnectionFactory()).destination(serverQueue())
       )
       .get();

问题在于,像requestRepository::save处理程序链之类的代码被破坏了。只有在作为处理程序参数传入网关时,此技巧才有效。

我如何克服这个限制?我认为在这里使用wireTap不会成交,因为它是异步的。实际上,在这里,我保存消息以存储它的jms_replyTo标题,并在从服务器(智能代理企业集成模式)返回相应的答复后将其替换为已保存的标题。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

不确定为什么要说"最后一个问题"。你会放弃Spring Integration吗? : - (

我猜您的问题出现在下一个.handle(),因为您的requestRepository::save是单向MessageHandlervoid方法的save()返回)。或者您的save()返回null

IntegrationFlow是一个执行链,当下一个将在前一个之后调用它的非null结果。

所以,请分享您的requestRepository::save

<强>更新

  

也没有帮助将MessageHandler bean声明为(m) - &gt; requestRepository.save(m)并将其作为参数传递给handle(..)方法。

是的...我希望看到您requestRepository::save的签名。

所以,看。使用.handle()的方法参考,您应该确定您的方案。如果one-way处理了流量停止,那么就足以遵循org.springframework.messaging.MessageHandler合同。你的方法签名应该像这样:

public void myHandle(Message<?> message)

如果您想继续使用该流程,则应从服务方法中返回任何内容。该结果将成为下一个payload的{​​{1}}。 在这种情况下,您的方法应遵循.handle()合同。您的方法签名可能如下所示:

org.springframework.integration.dsl.support.GenericHandler

方法参考如何适用于public Bar myHandle(Foo foo, Map<String, Object> headers)

您应该了解这种.handle()样式的工作原理。前一个方法的输出是下一个方法的输入。在这种情况下,我们保护流程不受死代码的影响,例如method chain返回MessageHandler,但是有下一个流成员。这就是您看到void错误的原因。

答案 1 :(得分:0)

最后想出了解决方案:

@Bean
public MessageHandler requestPersistingHandler() {
    return new ServiceActivatingHandler(message -> {
        requestRepository.save(message);
        return message.getPayload();
    });
}

//...
@Bean
public IntegrationFlow requestFlow() {
    return IntegrationFlows.from(
            Jms.messageDrivenChannelAdapter(queueConnectionFactory()).destination(bookingQueue())
    )
            .wireTap(controlBusMessageChannel())
            .enrichHeaders(headerEnricherSpec -> headerEnricherSpec.header(JMS_REPLY_HEADER, responseQueue(), true))
            .handle(requestPersistingHandler())
            .handle(
                    Jms.outboundAdapter(queueConnectionFactory()).destination(serverQueue())
            )
            .get();
}

我只是不确定是否有更直接的方式。

唯一的问题是如何在enrichHeaders方法中更改“from-the-server”IntegrationFlow中的标头:不知道如何使用规范访问现有标头。