正如本手册开头的概述中所描述的,面向消息的框架(如Spring Integration)背后的主要动机之一是促进组件之间的松散耦合。 消息渠道起着重要作用,因为生产者和消费者不必相互了解。 但是,优点也有一些缺点。 在松散耦合的环境中,有些事情会变得更加复杂,一个例子是错误处理。Spring中文文档

将消息发送到通道时,最终处理该消息的组件可能与发送方在同一线程中运行,也可能不在线程中运行。 如果使用简单的默认值(当元素没有子元素且没有“task-executor”属性时),则消息处理发生在发送初始消息的同一线程中。 在这种情况下,如果抛出 an,它可以被发送者捕获,或者如果它是未捕获的,它可能会传播到发送方。 这与普通 Java 调用堆栈中的异常抛出操作的行为相同。DirectChannel<channel><queue>ExceptionRuntimeExceptionSpring中文文档

在调用方线程上运行的消息流可以通过邮件网关(请参阅邮件网关)或(请参阅 MessagingTemplate)调用。 无论哪种情况,默认行为都是向调用方抛出任何异常。 对于邮件网关,请参阅错误处理,详细了解如何引发异常以及如何配置网关以将错误路由到错误通道。 使用 a 或直接发送到 a 时,总是会向调用方抛出异常。MessagingTemplateMessagingTemplateMessageChannelSpring中文文档

添加异步处理时,事情变得更加复杂。 例如,如果“channel”元素确实提供了一个“queue”子元素(在Java&注解配置中),则处理消息的组件在与发送方不同的线程中运行。 使用 an 时也是如此。 发件人可能已将其放入频道并继续执行其他操作。 使用标准投掷技术无法将 T 直接扔回该发送者。 相反,处理异步进程的错误要求错误处理机制也是异步的。QueueChannelExecutorChannelMessageExceptionExceptionSpring中文文档

Spring Integration 通过将错误发布到消息通道来支持其组件的错误处理。 具体来说,成为 Spring Integration 的有效负载。 然后将其发送到消息通道,该通道以类似于“replyChannel”解析的方式进行解析。 首先,如果在发生请求时正在处理的请求包含“errorChannel”标头(标头名称在常量中定义),则将发送到该通道。 否则,错误处理程序将发送到 Bean 名称为 (这也定义为常量: )的“全局”通道。ExceptionErrorMessageMessageMessageExceptionMessageHeaders.ERROR_CHANNELErrorMessageerrorChannelIntegrationContextUtils.ERROR_CHANNEL_BEAN_NAMESpring中文文档

默认 Bean 由框架在内部创建。 但是,如果要控制设置,可以定义自己的设置。 下面的示例演示如何在 XML 配置中定义错误通道,该配置由容量为 :errorChannel500Spring中文文档

@Bean
QueueChannel errorChannel() {
    return new QueueChannel(500);
}
<int:channel id="errorChannel">
    <int:queue capacity="500"/>
</int:channel>
默认错误通道是 . 默认情况下,它有一个 as 订阅者,其日志记录级别和 subscription 顺序为 。 如果订阅了其他使用终结点,则可能会引发异常,并且您不希望抢占日志记录,请确保其他处理程序具有更高的顺序。PublishSubscribeChannelLoggingHandlerERROROrdered.LOWEST_PRECEDENCE - 100
默认错误通道是 . 默认情况下,它有一个 as 订阅者,其日志记录级别和 subscription 顺序为 。 如果订阅了其他使用终结点,则可能会引发异常,并且您不希望抢占日志记录,请确保其他处理程序具有更高的顺序。PublishSubscribeChannelLoggingHandlerERROROrdered.LOWEST_PRECEDENCE - 100

这里要了解的最重要的事情是,基于消息传递的错误处理仅适用于在 . 这不适用于在与发送方相同的线程中操作的处理程序引发的异常(例如,通过本节前面所述的 处理程序)。TaskExecutorDirectChannelSpring中文文档

当计划的轮询器任务执行中发生异常时,这些异常将包装在实例中并发送到“errorChannel”。 这是通过注入全局 bean 来完成的。 如果错误处理仍必须使用标准的“errorChannel”集成流逻辑完成,则建议将其用于任何自定义。 在这种情况下,可以使用已注册的 bean。ErrorMessageMessagePublishingErrorHandlertaskSchedulerMessagePublishingErrorHandlertaskSchedulerintegrationMessagePublishingErrorHandler
当计划的轮询器任务执行中发生异常时,这些异常将包装在实例中并发送到“errorChannel”。 这是通过注入全局 bean 来完成的。 如果错误处理仍必须使用标准的“errorChannel”集成流逻辑完成,则建议将其用于任何自定义。 在这种情况下,可以使用已注册的 bean。ErrorMessageMessagePublishingErrorHandlertaskSchedulerMessagePublishingErrorHandlertaskSchedulerintegrationMessagePublishingErrorHandler

若要启用全局错误处理,请在该通道上注册处理程序。 例如,您可以将 Spring Integration 配置为订阅 . 然后,该路由器可以根据类型将错误消息传播到多个通道。ErrorMessageExceptionTypeRoutererrorChannelExceptionSpring中文文档

从版本 4.3.10 开始,Spring Integration 提供了 和 . 您可以将它们用作发布实例的常规机制。 可以在任何错误处理方案中调用或扩展它们。 将此类扩展为可与重试一起使用的实现,例如 RequestHandlerRetryAdvice。 用于基于提供的异常和上下文构建。 它可以注入任何或. 存储在上下文中。 可以将其用作它创建的属性。 正是这样做的。ErrorMessagePublisherErrorMessageStrategyErrorMessageErrorMessageSendingRecovererRecoveryCallbackErrorMessageStrategyErrorMessageAttributeAccessorMessageProducerSupportMessagingGatewaySupportrequestMessageErrorMessageUtils.INPUT_MESSAGE_CONTEXT_KEYAttributeAccessorErrorMessageStrategyrequestMessageoriginalMessageErrorMessageDefaultErrorMessageStrategySpring中文文档

从版本 5.2 开始,框架组件引发的所有实例都包含组件资源和源,以确定异常中的配置点。 在 XML 配置的情况下,资源是 XML 文件路径,源代码是带有其属性的 XML 标记。 在 Java & Annotation 配置中,资源是一个类,源是一个方法。 在大多数情况下,目标集成流解决方案基于现成的组件及其配置选项。 当在运行时发生异常时,堆栈跟踪中不涉及任何最终用户代码,因为执行是针对 Bean 的,而不是针对其配置的。 包括 Bean 定义的资源和源有助于确定可能的配置错误,并提供更好的开发人员体验。MessageHandlingExceptionBeanDefinitionid@Configuration@BeanSpring中文文档

从版本 5.4.3 开始,默认错误通道配置为当此通道上没有订阅者时(例如,当应用程序上下文停止时),不会以静默方式忽略消息。 在这种情况下,会抛出一个,它可能会借用入站通道适配器的客户端回调,以否定地确认(或回滚)源系统中的原始消息,以便重新传递或将来考虑其他事项。 若要还原以前的行为(忽略未调度的错误消息),必须将全局集成属性设置为 。 有关详细信息,请参阅全局属性PublishSubscribeChannel 配置(如果手动配置全局)。requireSubscribers = trueMessageDispatchingExceptionspring.integration.channels.error.requireSubscribersfalseerrorChannelSpring中文文档

有关详细信息,另请参阅错误处理示例Spring中文文档