I'm trying to write a multithreaded implementation for JMS message processing from a queue.
I've tried with DefaultMessageListenerContainer and SimpleMessageListenerContainer classes.
The problem I have is that it seems like just a single instance of the MessageListener class gets ever instantiated, no matter how I configure it. This forces me to unnecessarily write stateless or thread-safe MessageListener implementations, since I have the ListenerContainer configured to use multiple threads (concurrentConsumers=8).
Is there an obvious solution to this that I'm overlooking?
This is by design. The MessageListener
is a dependency that you inject into Spring - it has no way of instantiating new ones.
This forces me to unnecessarily write stateless or thread-safe messageListener implementations
You make that sound like a bad thing. Making your MessageListener
is a very good idea, Spring just removes the temptation to do otherwise.
Maybe this answer is too late, but it may benefit others who're searching for it. In short, the answer is using CommonsPoolTargetSource
and ProxyFactoryBean
.
Check out this link for details: http://forum.springsource.org/showthread.php?34595-MDB-vs-MDP-concurrency
If you want to do something similar for topic, check this: https://stackoverflow.com/a/12668538/266103
Configuring "concurrentConsumers" is just enough to process messages concurrently. This doesn't mean you will have "n" instances of MessageListenerContainer. The MessageListenerContainer may span "tasks" internally to process the messages. Optionally, you may have to configure your logging accordingly to see the information associated with the underlying tasks/threads.
See "Tuning JMS message consumption in Spring" for more details.