是否可以根据抛出的异常为一个服务激活器使用 2 个不同的重试 bean?

Is it possible to use 2 different retry beans for one service activator depending on an Exception thrown?

我只想在 ConnectionException 的情况下对服务激活器进行认真的重试,对于其他异常,我不想使用重试或非常轻的重试。我可以使用什么配置?我的配置的本质如下:

<int:channel id="sDZCreationErrorChannel">
    <int:interceptors>
        <int:wire-tap channel="errorLogger"/>
    </int:interceptors>
</int:channel>

<int:channel id="sDZConnectionErrorChannel">
    <int:interceptors>
        <int:wire-tap channel="errorLogger"/>
    </int:interceptors>
</int:channel>

<int:chain input-channel="sDZCreationErrorChannel" output-channel="outboundMailChannel">
    <int-mail:header-enricher>
        <int-mail:to value="${integration.sdz.email.to}"/>
        <int-mail:subject value="${integration.sdz.email.subject.creation}"/>
    </int-mail:header-enricher>
    <int:transformer ref="integrationEmailTransformer" method="transformToEmail"/>
</int:chain>

<int:chain input-channel="sDZConnectionErrorChannel" output-channel="outboundMailChannel">
    <int-mail:header-enricher>
        <int-mail:to value="${integration.sdz.email.to}"/>
        <int-mail:subject value="${integration.sdz.email.subject.noconnection}"/>
    </int-mail:header-enricher>
    <int:transformer ref="integrationEmailTransformer" method="transformToEmail"/>
</int:chain>

<int:channel id="sDZCreationChannel">
    <int:queue/>
</int:channel>

<!-- Processing Creation Chain -->
<int:chain input-channel="sDZCreationChannel" output-channel="debugLogger" 
    auto-startup="#{environment.getProperty('sd.zoo.enabled') == 'connect'}">
    <int:poller fixed-delay="500" />
    <int:filter ref="sDZIntegrationExistingRequestSentFilter" method="filter"/>
    <int:transformer ref="sDZCreationTransformer" method="transformOrder"/>
    <int:service-activator ref="sDZCreationServiceImpl" method="activateConfirmationCodes">
        <int:request-handler-advice-chain>
            <ref bean="retryAdvice"/>
        </int:request-handler-advice-chain>
    </int:service-activator>
</int:chain>

<int:exception-type-router input-channel="errorChannel" default-output-channel="integrationDeadLetterErrorChannel">
    <int:mapping exception-type="com.smartdestinations.connect.integration.exception.sdz.SDZCreationResponseException" channel="sDZCreationErrorChannel"/>
    <int:mapping exception-type="com.smartdestinations.connect.integration.exception.sdz.SDZConnectionException" channel="sDZConnectionErrorChannel"/>
</int:exception-type-router>

不,您不能将一个重试建议与其他建议一起使用。 <request-handler-advice-chain> 策略是按照它们在 <request-handler-advice-chain> 中的配置顺序将一个建议包装到另一个建议中。因此,如果您先声明一个 retryAdvice 然后再声明一个,则在第二个完成其工作之前不会到达第一个。

我还没有看到完整的画面,但如何轻松实现您的要求,但我真的确定您应该处理自定义 RetryPolicy,您可以通过以下方式到达目标异常:

public boolean canRetry(RetryContext context) {
    Throwable t = context.getLastThrowable();
    ...
}

注意那个有用的 RetryContext 对象。

还有一个有趣的钩子作为 RetryListener 抽象,您可以使用它在 RetryContext 中设置一些额外的属性。例如在 SI RequestHandlerRetryAdvice:

public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
    context.setAttribute("message", messageHolder.get());
    return true;
}