Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Achieve Concurrency With a Non-Thread-Safe MessageListener

The answer to this question explains how to use prototype scope with <rabbit:listener-container/> in Spring AMQP when the listener is not thread-safe.

Another user asked (in a comment) how to configure the same environment using only Java Configuration.

like image 237
Gary Russell Avatar asked Feb 07 '23 23:02

Gary Russell


1 Answers

It's generally best practice to use stateless beans for listeners but when that's not possible, to configure @Prototype scope listener (and multiple containers) using only Java Configuration, you can use:

@Bean
public SimpleMessageListenerContainer container1() {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());
    container.setQueueNames("test.mismatch");
    container.setMessageListener(new MessageListenerAdapter(listener()));
    container.setMismatchedQueuesFatal(true);
    return container;
}

...

@Bean
public SimpleMessageListenerContainer containerN() {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());
    container.setQueueNames("test.mismatch");
    container.setMessageListener(new MessageListenerAdapter(listener()));
    container.setMismatchedQueuesFatal(true);
    return container;
}

@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public MyNotThreadSafeListener listener() {
    return new MyNotThreadSafeListener();
}

Remember that any dependencies injected into MyNotThreadSafeListener must also be prototype beans.

Bottom line is stateless beans are best.

like image 79
Gary Russell Avatar answered Apr 23 '23 18:04

Gary Russell