Following scenario: I have a
@RabbitListener
@RabbitListener
RetryOperationsInterceptor
@RabbitListener
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setMessageConverter(new CustomMessageConverter());
factory.setConnectionFactory(connectionFactory());
factory.setAcknowledgeMode(AcknowledgeMode.AUTO);
factory.setConcurrentConsumers(1);
factory.setMaxConcurrentConsumers(20);
Advice[] adviceChain = new Advice[] { interceptor() };
factory.setAdviceChain(adviceChain);
return factory;
}
@Bean
RetryOperationsInterceptor interceptor() {
return RetryInterceptorBuilder.stateless()
.maxAttempts(5)
.recoverer(new CustomRejectAndRecoverer())
.build();
}
CustomRejectAndRecoverer
public class CustomRejectAndRecoverer implements MessageRecoverer {
@Override
public void recover(Message message, Throwable cause) {
if (ExceptionUtils.getRootCause(cause) instanceof BusinessObjectNotFoundRuntimeException) {
throw new ListenerExecutionFailedException("Retry Policy Exhausted",
new AmqpRejectAndDontRequeueException(cause), message);
}
}
}
You currently need a different container factory for each different retry configuration.
In 2.0, we have added a new errorHandler
attribute to the annotation so each listener can have a customized error handler, regardless of the container factory it was created by.
This was in the first milestone release; the current milestone is M2 and M3 will be out shortly. The GA release is expected in June.