2015-12-29 3 views
3

Проблема: Я переношу из интерфейса интерфейса MessageListener в @RabbitListener. У меня была логика, как это, где я делал «пре» и «пост» обработки сообщений на MessageListener, унаследованный от нескольких классовКак подключиться до/после обработки сообщений с помощью @RabbitListener

пример:

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); 

} 

Вопрос: Есть ли способ Я могу добиться чего-то подобного, используя @RabbitListener аннотацию. Где я могу наследовать логику обработки до/после сообщения, не переустанавливая или не обрабатывая обработку сообщения до/после сообщения внутри каждой дочерней аннотации @RabbitListener и все время сохраняя подписи настраиваемых методов для ребенок @RabbitListener? Или это слишком жадно?

Примера желаемый результат:

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) { 
     //... 
    } 
} 

с обеими этого @RabbitListener (ы) с использованием тех же унаследованные обработок сообщений до/после

я вижу есть аргумент 'containerFactory' в @ RabbitListener аннотации, но я уже объявляю один в config ... и я действительно уверен, как добиться желаемого наследования с помощью customFactoryFactory.


Обновлено Ответ: Это то, что я в конечном итоге делает.

Совет Defintion:

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; 
    } 

объявить бобы: в вашем RabbitMQ конфигурации объявить совет как Spring бина и передать его в 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

Коррекция

Вы можете использовать цепочку консультаций в SimpleRabbitListenerContainerFactory, чтобы применить советы для слушателей, созданные для @RabbitListener; двумя аргументами являются Channel и Message.

Если вам нужно только принять меры, прежде чем вызывать слушателя, вы можете добавить MessagePostProcessor (s) в контейнер afterReceivePostProcessors.

+0

я исправил свой ответ; Я забыл, что мы выставляем свойство 'adviceChain' на контейнерной фабрике. –

0

Наследование невозможно здесь, потому что обработка аннотаций по методам POJO и реализация MessageListener - это совершенно разные истории.

Использование MessageListener у вас полностью контролируется поведение цели и container.

С аннотациями вы имеете дело только с POJO, без рамки. Конкретный MessageListener создан на фоне. И это полностью основано на аннотированном методе.

Я бы сказал, что мы можем достичь вашего требования, используя Spring AOP Framework.

Смотрите недавний вопрос и его ответы на этот вопрос: How to write an integration test for @RabbitListener annotation?