Is it possible to set prefetch count on @RabbitListener

Ruslan Stelmachenko picture Ruslan Stelmachenko · Jun 1, 2016 · Viewed 8.3k times · Source

I know it is possible to make SimpleMessageListenerContainer bean and set prefetch count and message listener here, like this:

@Bean
public SimpleMessageListenerContainer messageListenerContainer(
        ConnectionFactory rabbitConnectionFactory,
        Receiver receiver) {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(rabbitConnectionFactory);
    container.setQueueNames("hello");
    container.setMessageListener(new MessageListenerAdapter(receiver, "receive"));
    container.setPrefetchCount(1000);
    return container;
}

But how to set prefetch count for channel if I want to use declarative approach using @RabbitListener?

@Component
public class Receiver {

    private static final Logger log = LoggerFactory.getLogger(Receiver.class);

    @RabbitListener(queues = "hello") // how to set prefetch count here?
    public void receive(String message) {
        log.info(" [x] Received '{}'.", message);
    }

}

It is not possible?

Answer

Ruslan Stelmachenko picture Ruslan Stelmachenko · Jun 1, 2016

Solution according to @artem-bilan answer:

Declare RabbitListenerContainerFactory bean with prefetch count 10 in some @Configuration class:

@Bean
public RabbitListenerContainerFactory<SimpleMessageListenerContainer> prefetchTenRabbitListenerContainerFactory(ConnectionFactory rabbitConnectionFactory) {
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(rabbitConnectionFactory);
    factory.setPrefetchCount(10);
    return factory;
}

Receiver bean uses this factory bean:

@Component
public class Receiver {

    private static final Logger log = LoggerFactory.getLogger(Receiver.class);

    @RabbitListener(queues = "hello", containerFactory = "prefetchTenRabbitListenerContainerFactory")
    public void receive(String message) {
        log.info(" [x] Received '{}'.", message);
    }

    @RabbitListener(queues = "hello")
    public void receiveWithoutPrefetch(String message) {
        log.info(" [x] Received without prefetch '{}'.", message);
    }

}

Two listeners here is just for demo purpose.
With this configuration Spring creates two AMQP channels. One for each @RabbitListener. First with prefetch count 10 using our new prefetchTenRabbitListenerContainerFactory bean and second with prefetch count 1 using default rabbitListenerContainerFactory bean.