【问题标题】:Catching Spring Integration DSL misconfiguration exceptions?捕捉 Spring Integration DSL 错误配置异常?
【发布时间】:2019-03-21 14:25:45
【问题描述】:

在使用 DSL 时,有没有办法捕获 DestinationResolutionExceptionMessageDispatchingException?这些异常通常表示配置错误,但我不确定如何配置我的流程来捕获这些异常并应用一些自定义逻辑?

@SpringBootApplication
public class IntegrationMisconfigurationExampleApplication {
  public static void main(final String[] args) {
    SpringApplication.run(IntegrationMisconfigurationExampleApplication.class, args);
  }

  @Bean
  public IntegrationFlow loggingFlow() {
    return IntegrationFlows.from("input")
        .<String, String>transform(String::toUpperCase)
        // .nullChannel();
        .get();
  }

  @Bean
  public CommandLineRunner demo() {
    return args -> {
      final MessagingTemplate template = messagingTemplate();
      template.convertAndSend("input", "abc");
    };
  }

  @Bean
  public MessagingTemplate messagingTemplate() {
    return new MessagingTemplate();
  }
}

上面的例子抛出了一个DestinationResolutionException,因为loggingFlow.transformer#0没有被正确初始化。有没有办法捕捉这个异常?

【问题讨论】:

    标签: java spring spring-integration spring-integration-dsl


    【解决方案1】:

    这些异常是运行时错误。我们真的无法确定启动时的错误配置。

    捕获此类运行时异常并进行一些分析工作的方法是使用ExpressionEvaluatingRequestHandlerAdvice,您可以在端点配置的第二个参数中将其添加到transform(String::toUpperCase) 配置中:

    .<String, String>transform(String::toUpperCase, e-> e.advice(myExpressionEvaluatingRequestHandlerAdvice()))
    

    在参考手册中查看有关此建议的更多信息:https://docs.spring.io/spring-integration/docs/current/reference/html/#message-handler-advice-chain

    您还需要记住,transformer 确实是一个 request-reply 组件,具有必需的非空返回值。因此,您真的不能只为单向流配置transform()。当流中没有下一个通道或消息中没有replyChannel 标头时,它将抛出异常。

    【讨论】:

    • 我应该更好地解释我正在尝试做什么...我故意错误配置了转换器,因为这是我知道如何产生此异常的最简单方法。我也知道您无法确定它并且没想到您会,我真的在寻找e.advice :) 我尝试寻找e.errorChannel(...) 或类似的东西但找不到,没有考虑使用建议,谢谢!
    • errorChannel() 仅适用于网关或入站通道适配器。它仍然像请求消息中的标头。在该入站组件上处理此类错误。但是如果你直接发送消息,你会在调用者中得到一个异常。只有在当前组件中本地处理它的方法是通过提到的建议。
    • 还有一件事,是否可以为整个流程注册一个建议,而不仅仅是一个组件?因此,如果有多个 .transform(...) 方法,我不必为每个方法注册建议吗?这可能需要一个新问题?
    • 不,那不是。这样的建议是针对每个端点的。整个流程只是一个逻辑容器,在运行时没有关于流程与其声明的端点之间的交互。