Spring:IdempotentReceiverInterceptor只能在MessageHandlers上使用?

时间:2016-07-01 16:45:00

标签: java spring-integration

我正在尝试使用IdempotentReceiverInterceptor来阻止我的集成流发出它已经生成的消息。但是,似乎IdempotentReceiverInterceptor#invoke只需要扩展MessageHandler的组件(在某种程度上)或者有一个名为“handleMessage”的方法,其第一个参数是Message。我想对消息进行重复数据删除,如果消失,请执行一些额外的处理。

我的问题有两个:

  • 是否有理由不允许任何此建议 零件; Transformer,GenericHandler等?
  • 因为它只允许在MessageHandler或任何具有handleMessage方法的东西上运行,所以我尝试使用AbstractReplyProducingMessageHandler(因为我需要进行额外的处理),但这也不起作用。

我觉得我误解了IdempotentReceiverInterceptor的正确使用,我应该能够在几乎任何组件上使用它,但实现似乎并不同意我的看法。我不知道应该如何使用它或我使用它错了吗?我知道我可能只是将MetadataStoreSelector作为过滤器抛入流中,但我正在尝试按照SI的建议做事。

感谢任何帮助。这是我希望工作的示例流程。

return IntegrationFlows
    .from(messageProducer)
    .<String, UUID>transform(s -> UUID.fromString(s))
    .claimCheckOut(messageStore)
    .handle(
        new AbstractReplyProducingMessageHandler() {

          @Override
          protected Object handleRequestMessage(final Message<?> requestMessage) {
            return requestMessage;
          }

        },
        spec -> {
          spec.advice(idempotentReceiverInterceptor);
        })
    // do some more stuff
    .transform(transformer)
    .handle(loggingHandler)
    .get();

这是显示它没有

的日志消息
This advice org.springframework.integration.handler.advice.IdempotentReceiverInterceptor can only be used for MessageHandlers; an attempt to advise method 'toString' in 'org.springframework.integration.handler.AbstractReplyProducingMessageHandler$AdvisedRequestHandler' is ignored

编辑:对于那些来这里寻找解决方案的人来说,这几乎就是我最后做的事情

return IntegrationFlows
    .from(messageProducer)
    .<String, UUID>transform(s -> UUID.fromString(s))
    .claimCheckOut(messageStore)
    .filter(metadataStoreSelector)
    // do some more stuff
    .transform(transformer)
    .handle(loggingHandler)
    .get();

1 个答案:

答案 0 :(得分:1)

根据Reference Manual

  

这是一个AOP建议,适用于MessageHandler.handleMessage()方法,可根据其配置过滤请求消息或将其标记为重复。

源代码说:

boolean isMessageHandler = invocationThis != null && invocationThis instanceof MessageHandler;
boolean isMessageMethod = method.getName().equals("handleMessage")
        && (arguments.length == 1 && arguments[0] instanceof Message);

换句话说,MessageHandler只会影响IdempotentReceiverInterceptor个实施。

那个。

您无需担心TransformerGenericHandler。框架最终会以特定的MessageHandler包装结束,例如ServiceActivatingHandlerMessageTransformingHandler等所有这些只是因为它就像Spring Integration中的契约:channel -> endpoint -> messageHandler

那是两个。

由于IdempotentReceiverInterceptor的主要前提是将逻辑完全应用于消费者端点(请参阅其文档),因此您无法在spec.advice()中使用它,因为这恰好是handleRequestMessage(),正如您所料。但这并不适用于IdempotentReceiverInterceptor

是的......遗憾的是,没有那么简单的方法可以通过Java DSL风格来利用它。虽然您可以通过消息渠道区分您的流量,并将@ServiceActivator@Transformer)与@IdempotentReceiver一起提取到单独的@Service中,直到我们找到&#34;的解决方案。生&#34; Java配置。

随时可以就此事提出JIRA票。我认为ConsumerEndpointFactoryBean应该将IdempotentReceiverInterceptoradvice中的所有其他内容区分开来,并最终将其正确应用于handleMessage。因此,您的预期配置将起作用。

感谢您发现它!