26 September, 2013

SimpleMessageListenerContainer autoStartup and connectLazily properties

   Lately after replacing DefaultMessageListenerContainer with SimpleMessageListenerContainer I spotted that the second one ignores autoStartup setting.
Spring documentation states that SimpleMessageListenerContainer creates a fixed number of JMS sessions at startup and uses them throughout the lifespan of the container, but why this happens before checking the autoStartup flag. I chose to explore source code for an answer.
   Initialization of MessageListenerContainers is done automatically when context starts up, as they implement the Lifecycle interface. It is worth to remember that lazy-init flag is ignored for lifecycle beans.
 Let’s look how the initialization flow looks like:
  • constructor
  • set properties (here auto start-up flag is set)
  • post construct method – if defined
  • doInitialize
  • doStart
Execution of doStart method depends on autoStartup flag which is checked in DefaultLifecycleProcessor.startBeans. Both containers use AbstractJmsListeningContainer’s doStart implementation:
  • default container doesn’t override it at all
  • simple container executes it and after that initializes consumers
  • @Override
    protected void doStart() throws JMSException {
          super.doStart();
          initializeConsumers();
    }
    
doStart establishes shared connection and resume all defined tasks. Default container task creates connection, session and consumer. Simple container doesn’t define any asynchronous tasks, instead it creates all these JMS components synchronously in its doInitialize method. So consumers initialization in doStart method is redundant in this case.

Since Spring 3.1 SimpleMessageListenerContainer has additional property connectLazily,that can be used to skip initialization of JMS components in doInitialize method. When this flag is set to true and autoStartup to false, then message listener container needs to be started manually.