¿Cómo nos conectamos al procesamiento de mensajes antes / después usando @RabbitListener?
Problema: Estoy migrando de la interfaz de MessageListener implícitamente a @RabbitListener. Tenía una lógica como esta donde estaba haciendo el procesamiento de mensajes "pre" y "post" en un MessageListener que fue heredado por varias clases
ejemplo:
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);
}
Pregunta: ¿Hay alguna manera de lograr algo similar usando la anotación @RabbitListener? Donde puedo heredar la lógica de procesamiento de mensajes pre / post sin tener que volver a implementar o llamar al procesamiento de mensajes pre / post dentro de cada anotación @RabbitListener secundaria y todo mientras mantengo una personalización firmas de método para el niño @RabbitListener? ¿O es esto demasiado codicioso?
Ejemplo de resultado deseado:
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) {
//...
}
}
con ambos @RabbitListener (s) que utilizan el mismo procesamiento heredado de mensajes pre / post
Veo que hay un argumento 'containerFactory' en la anotación @RabbitListener, pero ya estoy declarando uno en la configuración ... y estoy realmente seguro de cómo lograr la herencia que deseo con un containerFactory personalizado.
Respuesta actualizada: Esto es lo que terminé haciendo.
Consejo de definición:
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;
}
declarar frijoles: En su configuración de rabbitmq, declare el consejo como un bean Spring y páselo a rabbitListenerContainerFactory # setAdviceChain (...)
//...
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory( cachingConnectionFactory() );
factory.setTaskExecutor(threadPoolTaskExecutor());
factory.setMessageConverter(jackson,2JsonMessageConverter());
factory.setAdviceChain(rabbitListenerAroundAdvice());
return factory;
}
@Bean
public RabbitListenerAroundAdvice rabbitListenerAroundAdvice() {
return new RabbitListenerAroundAdvice();
}
// ...