带有重试建议的 Jms 消息失败将响应发送到失败通道并再次传递到成功通道

Jms message failure with Retry advice send response to fail channel and again pass to successful channel

配置如下

<jms:outbound-channel-adapter id="someId" channel="inputChannel"
                                  connection-factory="${connection.factory}"  destination="queue">
        <jms:request-handler-advice-chain>
            <bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
                <property name="onSuccessExpression" value="T(Boolean).TRUE"/>
                <property name="successChannelName" value="afterSuccessDeliveryMessageChannel"/>
                <property name="onFailureExpression" value="T(Boolean).FALSE"/>
                <property name="failureChannelName" value="failureChannel"/>
            </bean>
            <bean id="retryWithBackoffAdviceSession"
                  class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
                <property name="retryTemplate">
                    <bean class="org.springframework.retry.support.RetryTemplate">
                        <property name="retryPolicy">
                            <bean class="org.springframework.retry.policy.SimpleRetryPolicy">
                                <property name="maxAttempts" value="5"/>
                            </bean>
                        </property>
                    </bean>
                </property>
                <property name="recoveryCallback">
                    <bean class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer">
                        <constructor-arg ref="failureChannel"/>
                    </bean>
                </property>
            </bean>
        </jms:request-handler-advice-chain>
    </jms:outbound-channel-adapter>

我正在重试消息 5 次,然后使用 recoveryCallBack 将消息记录到某个数据库。 它可以正常重试 5 次并调用 failureChannel 通道,但是一旦它调用 failureChannel 然后它再次传递给 afterSuccessDeliveryMessageChannel.

我不确定我做错了什么? 我期待一旦它失败它应该去 failedChannel 而不是再次回到 afterSuccessDeliveryMessageChannel.

你的问题是这样的:

您的重试建议从 recoveryCallback 发送到 failureChannel 并成功退出。

然后当我们查看 ExpressionEvaluatingRequestHandlerAdvice 代码时,我们会看到这样的逻辑:

 try {
        Object result = callback.execute();
        if (this.onSuccessExpression != null) {
            evaluateSuccessExpression(message);
        }
        return result;
    }

因此,由于没有异常调用callback,它会转到配置的successChannel

要让它失败并转到配置的failureChannel,你应该考虑不要使用那个recoveryCallback。然后 RequestHandlerRetryAdvice 将抛出一个异常,该异常将被 ExpressionEvaluatingRequestHandlerAdvice 捕获并发送给 failureChannel。不会有 onSuccessExpression 评估,因为我们最终会出现异常。