java - 如何组织 Spring Integration 重试方法,其列表随着每次重试而减少?

标签 java spring spring-integration spring-retry

有以下带有重试功能的 Spring Integration 配置:

<int:chain input-channel="sdCreationChannel" output-channel="debugLogger">
    <int:poller fixed-delay="500" />
    <int:filter ref="sdIntegrationExistingRequestSentFilter" method="filter"/>
    <int:service-activator ref="sdCreationServiceImpl" method="processMessage">
        <int:request-handler-advice-chain>
            <ref bean="retryAdvice"/>
        </int:request-handler-advice-chain>
    </int:service-activator>
</int:chain>

<bean id="retryAdvice" class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice" >
    <property name="retryTemplate">
        <bean class="org.springframework.retry.support.RetryTemplate">
            <property name="backOffPolicy">
                <bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
                    <property name="initialInterval" value="${integration.retry.initial.delay}"/>
                    <property name="multiplier" value="${integration.retry.backoff.multiplier}"/>
                </bean>
            </property>
            <property name="retryPolicy">
                <bean class="org.springframework.retry.policy.SimpleRetryPolicy">
                    <property name="maxAttempts" value="${integration.retry.max.attempts}" />
                </bean>
            </property>
        </bean>
    </property>
</bean>

简化后的Java代码如下:

@Component("sdCreationServiceImpl")
public class SDCreationServiceImpl implements SDCreationService {

@Autowired
private NotifySD  notifySD;
@Override
public void processMessage(IntegrationPayload integrationPayload) {
List<ConfirmationCode> sdConfCodes = findCodesFromPayLoad(integrationPayload);
    notifySD.activateConfirmationCodes(sdConfCodes);

}  

重试此代码的问题在于,List sdConfCodes 可以在每次重试时部分处理,因此每次我们需要发送处理较少数量的元素。组织此代码的最佳方式是什么?

按照Artem Bilan的建议(谢谢!)我在SDCreationServiceImpl中创建了带有变量列表的第二个方法,即activateConfirmationCodes,然后在XML规范中指出该方法作为sdCreationServiceImpl的方法。

@Component("sdCreationServiceImpl")
public class SDCreationServiceImpl implements SDCreationService {
@Autowired
private NotifySD  notifySD;
List<ConfirmationCode> sdConfCodes = new ArrayList<ConfirmationCode()>;
@Override
public void processMessage(IntegrationPayload integrationPayload) {
sdConfCodes = findCodesFromPayLoad(integrationPayload);
}  

public void activateConfirmationCodes()
{
    notifySD.activateConfirmationCodes(sdConfCodes);
}

然后service-activator的XML规范如下:

<int:service-activator ref="sdCreationServiceImpl" method="activateConfirmationCodes">
<int:request-handler-advice-chain>
<ref bean="retryAdvice"/>
</int:request-handler-advice-chain>
</int:service-activator>

是的,这个方法 activateConfirmationCodes 在 Retry 中被调用,但是第一个方法 processMessage 根本没有被调用。 是否可以指定一种方法在第一次尝试时调用,另一种方法在重试时调用? 其次,通过这种设计,列表变成单例,这可能会在多线程中出现问题,对吗?该列表是否可以与仅用于特定消息的 bean 相关联?

最佳答案

从大的角度来看,不清楚你的问题出在哪里。从另一个角度来说说我的一些想法,也许我能猜到你的目的。

拥有 List<ConfirmationCode>作为payload允许我们随时修改它。因此,假设我们的列表为 10元素。第一次尝试我们已经处理了其中的 3 个。第四次失败了。我们必须去重试抛出一些适当的异常。 但我们回到了重试感知方法的开头,所以使用相同的参数。如果我们从集合中删除这些成功的项目,则下一次重试迭代将根本不会处理它们。

从一方面来说,您可以实现与众不同的 findCodesFromPayLoad()服务和activateConfirmationCodes() ,对最后一个应用重试。

从另一面,您可以将项目标记为已处理 activateConfirmationCodes() ,所以下一个findCodesFromPayLoad(integrationPayload)不会归还它们。

换句话说,有足够的方法可以在不更改消息的情况下修改集合。

关于java - 如何组织 Spring Integration 重试方法,其列表随着每次重试而减少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34730074/

相关文章:

java - AppEngine 将我的 POST 请求处理为 GET

java - partitioningBy的目的是什么

java - JSoup 选择器包含两个元素

java - 在私有(private)方法中保存实体

spring-integration - Spring 集成 DSL : configure handler that handles only when the argument matches

java - spring-rabbitmq 自动重试连接到代理

java - 在不使用 Java.Runtime 的情况下用 Java 解密 gpg

mysql - 尝试从 spring mvc 应用程序在 mysql 中插入数据时获取 java.io.EOFException

java - Apache Camel bean 参数与 Spring DSL 的绑定(bind)问题

java - 如何中断或取消 Spring Integration Java DSL 流程?