How to connect before / after message processing using @RabbitListener

Problem: I am migrating from the MessageListener interface interface to @RabbitListener. I had this logic when I was processing the messages "pre" and "post" on a MessageListener inherited from several classes

example:

public AbstractMessageListener implements MessageListener { @Override public void onMessage(Message message) { //do some pre message processing process(Message message); // do some post message processing } protected abstract void process(Message message); } 

Question: Is there a way I can achieve something like this using the @RabbitListener annotation. Where can I inherit the processing logic before / after the message without having to re-implement or invoke the processing of the message before / after the message inside each @RabbitListener child annotation and all the while supporting custom method signatures for the @RabbitListener child? Or is it too greedy?

An example of the desired result:

 public class SomeRabbitListenerClass { @RabbitListener( id = "listener.mypojo",queues = "${rabbitmq.some.queue}") public void listen(@Valid MyPojo myPojo) { //... } } public class SomeOtherRabbitListenerClass { @RabbitListener(id = "listener.orders",queues ="${rabbitmq.some.other.queue}") public void listen(Order order, @Header("order_type") String orderType) { //... } } 

for both of these @RabbitListener (s) using the same inherited pre / post message processing

I see that the @RabbitListener annotation has an argument of 'containerFactory', but I already declare it in config ... and I'm really sure how to achieve the desired inheritance with customFactoryFactory.


Updated answer: This is what I ended up doing.

Tip:

 import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.amqp.core.Message; /** * AOP Around advice wrapper. Every time a message comes in we can do * pre/post processing by using this advice by implementing the before/after methods. * @author sjacobs * */ public class RabbitListenerAroundAdvice implements MethodInterceptor { /** * place the "AroundAdvice" around each new message being processed. */ @Override public Object invoke(MethodInvocation invocation) throws Throwable { Message message = (Message) invocation.getArguments()[1]; before(message) Object result = invocation.proceed(); after(message); return result; } 

declare beans: In the rabbitmq configuration, declare the advice as a Spring bean and pass it to rabbitListenerContainerFactory # setAdviceChain (...)

 //... @Bean public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setConnectionFactory( cachingConnectionFactory() ); factory.setTaskExecutor(threadPoolTaskExecutor()); factory.setMessageConverter(jackson2JsonMessageConverter()); factory.setAdviceChain(rabbitListenerAroundAdvice()); return factory; } @Bean public RabbitListenerAroundAdvice rabbitListenerAroundAdvice() { return new RabbitListenerAroundAdvice(); } // ... 
+3
spring-amqp spring-rabbit
source share
2 answers

Correction

You can use the consultation chain in SimpleRabbitListenerContainerFactory to apply advice to listeners created for @RabbitListener ; two arguments are Channel and Message .

If you only need to complete the action before calling the listener, you can add MessagePostProcessor (s) to the afterReceivePostProcessors container.

+3
source share

Inheritance is not possible here, because processing annotations using POJO methods and implementing MessageListener are completely different stories.

Using MessageListener , you have complete control over the behavior of the target and container .

With annotations, you only deal with POJO code, no frame. A specific MessageListener is created in the background. And it is completely based on the annotated method.

I would say that we can achieve your requirement using the Spring AOP Framework.

See a recent question and its answers on this question: How to write an integration test for @RabbitListener annotation?

0
source share

All Articles