My container XML config:
<rabbit:listener-container
connection-factory="myConnectionFactory"
acknowledge="none"
concurrency="10"
requeue-rejected="false">
<rabbit:listener ref="myListener" queues="myQueue"/>
</rabbit:listener-container>
and myListener
is just a class
@Component("myListener")
public class MyListener implements MessageListener {
@Autowired
SomeDependency dependency;
....
}
I've specified concurrency="10"
in my XML. What does this mean exactly?
I've found some docs. They are not that helpful stating:
Specify the number of concurrent consumers to create. Default is 1.
What I am interested in is whether MyListener
has to be thread safe i.e.
SomeDependency dependency
instantiated once or for each thread/instance?dependency
need to be thread safe?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.