入站适配器上没有 errorChannel 的异常行为

Exception Behaviour without errorChannel on inbound adapters

我有 int-aws:sqs-message-driven-channel-adapter,如果我在上面设置 errorChannel,下游异常就会出现。

但是,当我不设置 errorChannel 时,不会记录异常。它不会转到预期的 errorChannel。有没有办法至少记录此类异常?是否有默认的 errorlogger 可以简单地记录此类错误?

更新

根据评论发布 XMLDSL 配置。通过为 ServiceObject.

上的 @NotBlank 字段设置 null,在持久层中模拟 error
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:int="http://www.springframework.org/schema/integration"
    xmlns:int-aws="http://www.springframework.org/schema/integration/aws"
    xmlns:int-jpa="http://www.springframework.org/schema/integration/jpa"
    xmlns="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
       http://www.springframework.org/schema/integration/jpa https://www.springframework.org/schema/integration/jpa/spring-integration-jpa.xsd
       http://www.springframework.org/schema/integration/aws https://www.springframework.org/schema/integration/aws/spring-integration-aws.xsd">

  <int:channel id="serviceLogChannel">
    <int:interceptors>
      <int:wire-tap channel="loggingChannel"/>
    </int:interceptors>
  </int:channel>

  <int-aws:sqs-message-driven-channel-adapter sqs="amazonSQS"
      auto-startup="true"
      channel="serviceLogChannel"
      id="sqsMessageDrivenChannelAdapter"
      queues="${app.queue-name}"
      max-number-of-messages="10"
      visibility-timeout="5"
      wait-time-out="20"
      error-channel="errorChannel"/>

  <int:chain input-channel="serviceLogChannel">
    <int:json-to-object-transformer type="ServiceObject"/>
    <int-jpa:outbound-channel-adapter entity-class="ServiceObject"
        persist-mode="PERSIST"
        entity-manager-factory="entityManagerFactory">
      <int-jpa:transactional/>
    </int-jpa:outbound-channel-adapter>
  </int:chain>

  <int:logging-channel-adapter log-full-message="true"
      logger-name="tapInbound"
      id="loggingChannel"/>

  <int:service-activator input-channel="errorChannel" expression="@reThrow.rethrow(payload)" order="100"/>

</beans>

ReThrow 服务激活器:

@Component
public class ReThrow {

    public void rethrow(Exception exception) throws Exception {
        throw exception;
    }

}

相同的 DSL 配置是:

@Configuration
public class IntegrationConfiguration {

    @Bean
    public MessageProducer createSqsMessageDrivenChannelAdapter(
        AmazonSQSAsync amazonSQSAsync,
        MessageChannel serviceChannel,
        MessageChannel errorChannel,
        @Value("${app.queue-name}") String queueName) {
        SqsMessageDrivenChannelAdapter adapter =
            new SqsMessageDrivenChannelAdapter(amazonSQSAsync, queueName);
        adapter.setVisibilityTimeout(5);
        adapter.setWaitTimeOut(20);
        adapter.setAutoStartup(true);
        adapter.setMaxNumberOfMessages(10);
        adapter.setOutputChannel(serviceChannel);
        adapter.setErrorChannel(errorChannel);
        adapter.setMessageDeletionPolicy(SqsMessageDeletionPolicy.NO_REDRIVE);
        return adapter;
    }

    @Bean
    public IntegrationFlow messageProcessingFlow(
        MessageChannel serviceChannel, EntityManagerFactory entityManagerFactory) {

        return IntegrationFlows.from(serviceChannel)
            .transform(Transformers.fromJson(ServiceObject.class))
            .handle(
                Jpa.outboundAdapter(entityManagerFactory)
                    .entityClass(ServiceObject.class)
                    .persistMode(PersistMode.PERSIST),
                e -> e.transactional())
            .get();
    }


    @Bean
    public IntegrationFlow errorProcessingFlow(MessageChannel errorChannel) {

        return IntegrationFlows.from(errorChannel)
            .handle(
                m -> {
                    throw (RuntimeException) m.getPayload();
                })
            .get();
    }

    @Bean
    public MessageChannel serviceChannel() {
        return MessageChannels.publishSubscribe().get();
    }
}

SqsMessageDrivenChannelAdapter 完全基于来自 Spring Cloud AWS 的 SimpleMessageListenerContainerFactory,它只是委托给我们提供的监听器。查看代码,没有任何错误处理。因此,目前处理它的最佳方法是显式设置 error-channel="errorChannel" 并将通过订阅该全局 errorChannel.

的默认记录器进行记录

是的:默认情况下不会转到 errorChannel。我不确定我们的文档中是否有这样的官方声明。最好将其视为“默认情况下无错误通道”,因此由底层协议客户端来处理抛出的错误。既然那里没有人,那么我们别无选择,除非明确设置错误通道。