使用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,但根本不调用第一个方法processMessage。 是否可以指定一种方法在第一次尝试时调用,另一种方法可以重试? 第二,使用这种设计,列表成为单例,这可能会给多线程带来问题,对吗?此列表是否只能与特定消息的bean关联?
答案 0 :(得分:2)
从大到现在还不清楚你的问题在哪里。从另一方面让我分享一些我的想法,也许我会猜测你的目标。
将List<ConfirmationCode>
作为payload
,我们可以随时修改它。所以,我们假设我们列出了10
个元素。在第一次尝试时,我们处理了其中3个。第四次失败了。我们必须重试一些适当的例外。
但是我们回到了重试感知方法的开头,所以使用相同的参数。如果我们从集合中删除那些成功的项目,则下一次重试迭代根本不会处理它们。
从一方面,您可以实现区分findCodesFromPayLoad()
服务和activateConfirmationCodes()
,对最后一个应用重试。
从另一方面,您可以将项目标记为activateConfirmationCodes()
中处理的项目,以便下一个findCodesFromPayLoad(integrationPayload)
赢回来。
换句话说,有足够的方法可以在不改变消息的情况下修改集合。