How to Achieve Concurrency With a Non-Thread-Safe

2019-02-18 00:26发布

问题:

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.

回答1:

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.