I've a listener like the following :
@RabbitListener(queues = "${myQueue}")
public void receiveMessages(Message message) {
doTheBusinessLogic(message)
}
I understand from here What is the ServletFilter equalent of a RabbitMq Listener?
that we can execute some logic before getting inside the listener (an 'interceptor'), using Advice :
see the following code :
@Bean(name = "rabbitListenerContainerFactory")
public SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory(
SimpleRabbitListenerContainerFactoryConfigurer configurer,
ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
configurer.configure(factory, connectionFactory);
factory.setAdviceChain(new MDCAdvice());
return factory;
}
So my question is : if i throw a runtime exception from inside an advice (like this MDCAdvice) is it like i throw it from inside the listener method ?
public static class MDCAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
// pre process
if (throwBefore) throw new RuntimeException("before")
try {
return invocation.proceed();
}
finally {
// post process
throw new RuntimeException("after")
}
}
}
I mean : is a NACK returned to rabbitmq ? Is the transaction rolled back if the listener is transactional ?
In general, is totally equivalent to throw it inside the doTheBusinessLogic(message) above ?
Thank you for your help
Yes; any exception thrown in the advice(s) will cause the same behavior as if the exception was thrown in the listener itself.
For example, if you want to discard a message, throw a AmqpRejectAndDontRequeueException
.
You can achieve the same by using a MessagePostProcessor
(in the afterReceivePostProcessors
and return null
.