Gary Russell
Gary Russell

Reputation: 174484

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.

Upvotes: 4

Views: 1939

Answers (1)

Gary Russell
Gary Russell

Reputation: 174484

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.

Upvotes: 8

Related Questions