Yes, to use concurrency, your listener has to be thread-safe. There is one listener instance per container. However, the <rabbit:listener-container/>
namespace element is actually just a convenience for adding "shared" attributes, each listener element gets its own container.
It's generally best to use stateless objects (no fields that are written to), but that's not always possible.
If your listener is not thread-safe, you can use...
<rabbit:listener-container
connection-factory="myConnectionFactory"
acknowledge="none"
requeue-rejected="false">
<rabbit:listener ref="myListener" queues="myQueue"/>
<rabbit:listener ref="myListener" queues="myQueue"/>
<rabbit:listener ref="myListener" queues="myQueue"/>
<rabbit:listener ref="myListener" queues="myQueue"/>
...
</rabbit:listener-container>
...and add @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
. You will then get a container for each listener and a different instance of the listener will be injected into each.
You will also need prototype scope for any non-thread-safe dependencies injected into the listener.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…