org.springframework.jms.listener

## Class SimpleMessageListenerContainer

- java.lang.Object
- - org.springframework.jms.support.JmsAccessor
  - - org.springframework.jms.support.destination.JmsDestinationAccessor
    - - org.springframework.jms.listener.AbstractJmsListeningContainer
      - - org.springframework.jms.listener.AbstractMessageListenerContainer
        - - org.springframework.jms.listener.SimpleMessageListenerContainer

- All Implemented Interfaces:
    ExceptionListener, Aware, BeanNameAware, DisposableBean, InitializingBean, Lifecycle, Phased, SmartLifecycle, MessageListenerContainer

      public class SimpleMessageListenerContainer
      extends AbstractMessageListenerContainer
      implements ExceptionListener

  Message listener container that uses the plain JMS client API's `MessageConsumer.setMessageListener()` method to create concurrent MessageConsumers for the specified listeners.

  This is the simplest form of a message listener container. It creates a fixed number of JMS Sessions to invoke the listener, not allowing for dynamic adaptation to runtime demands. Its main advantage is its low level of complexity and the minimum requirements on the JMS provider: Not even the ServerSessionPool facility is required.

  See the `AbstractMessageListenerContainer` javadoc for details on acknowledge modes and transaction options. Note that this container exposes standard JMS behavior for the default "AUTO_ACKNOWLEDGE" mode: that is, automatic message acknowledgment after listener execution, with no redelivery in case of a user exception thrown but potential redelivery in case of the JVM dying during listener execution.

  For a different style of MessageListener handling, through looped `MessageConsumer.receive()` calls that also allow for transactional reception of messages (registering them with XA transactions), see `DefaultMessageListenerContainer`.

  Since:
    2.0
  Author:
    Juergen Hoeller
  See Also:
    `MessageConsumer.setMessageListener(javax.jms.MessageListener)`, `DefaultMessageListenerContainer`, `JmsMessageEndpointManager`

- - ### Nested Class Summary

    - ### Nested classes/interfaces inherited from class org.springframework.jms.listener.AbstractJmsListeningContainer

      `AbstractJmsListeningContainer.SharedConnectionNotInitializedException`

  - ### Field Summary

    - ### Fields inherited from class org.springframework.jms.listener.AbstractJmsListeningContainer

      `lifecycleMonitor, sharedConnectionMonitor`

    - ### Fields inherited from class org.springframework.jms.support.destination.JmsDestinationAccessor

      `RECEIVE_TIMEOUT_INDEFINITE_WAIT, RECEIVE_TIMEOUT_NO_WAIT`

    - ### Fields inherited from class org.springframework.jms.support.JmsAccessor

      `logger`

    - ### Fields inherited from interface org.springframework.context.SmartLifecycle

      `DEFAULT_PHASE`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `SimpleMessageListenerContainer()`

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `protected MessageConsumer` | `createListenerConsumer(Session session)` Create a MessageConsumer for the given JMS Session, registering a MessageListener for the specified listener.
    `protected void` | `doInitialize()` Creates the specified number of concurrent consumers, in the form of a JMS Session plus associated MessageConsumer.
    `protected void` | `doShutdown()` Destroy the registered JMS Sessions and associated MessageConsumers.
    `protected void` | `doStart()` Re-initializes this container's JMS message consumers, if not initialized already.
    `protected void` | `initializeConsumers()` Initialize the JMS Sessions and MessageConsumers for this container.
    `void` | `onException(JMSException ex)` JMS ExceptionListener implementation, invoked by the JMS provider in case of connection failures.
    `protected void` | `prepareSharedConnection(Connection connection)` Registers this listener container as JMS ExceptionListener on the shared connection.
    `protected void` | `processMessage(Message message, Session session)` Process a message received from the provider.
    `void` | `setConcurrency(String concurrency)` Specify concurrency limits via a "lower-upper" String, e.g.
    `void` | `setConcurrentConsumers(int concurrentConsumers)` Specify the number of concurrent consumers to create.
    `void` | `setConnectLazily(boolean connectLazily)` Specify whether to connect lazily, i.e.
    `void` | `setRecoverOnException(boolean recoverOnException)` Specify whether to explicitly recover the shared JMS Connection and the associated Sessions and MessageConsumers whenever a JMSException is reported.
    `void` | `setTaskExecutor(Executor taskExecutor)` Set the Spring TaskExecutor to use for executing the listener once a message has been received by the provider.
    `protected boolean` | `sharedConnectionEnabled()` Always use a shared JMS Connection.
    `protected void` | `validateConfiguration()` Validate the configuration of this container.

    - ### Methods inherited from class org.springframework.jms.listener.AbstractMessageListenerContainer

      `checkMessageListener, commitIfNecessary, createConsumer, doExecuteListener, doInvokeListener, doInvokeListener, executeListener, getDefaultSubscriptionName, getDestination, getDestinationDescription, getDestinationName, getDurableSubscriptionName, getErrorHandler, getExceptionListener, getMessageConverter, getMessageListener, getMessageSelector, getReplyQosSettings, getSubscriptionName, handleListenerException, invokeErrorHandler, invokeExceptionListener, invokeListener, isAcceptMessagesWhileStopping, isExposeListenerSession, isPubSubNoLocal, isReplyPubSubDomain, isSessionLocallyTransacted, isSubscriptionDurable, isSubscriptionShared, rollbackIfNecessary, rollbackOnExceptionIfNecessary, setAcceptMessagesWhileStopping, setDestination, setDestinationName, setDurableSubscriptionName, setErrorHandler, setExceptionListener, setExposeListenerSession, setMessageConverter, setMessageListener, setMessageSelector, setPubSubNoLocal, setReplyPubSubDomain, setReplyQosSettings, setSubscriptionDurable, setSubscriptionName, setSubscriptionShared, setupMessageListener`

    - ### Methods inherited from class org.springframework.jms.listener.AbstractJmsListeningContainer

      `afterPropertiesSet, createSharedConnection, destroy, doRescheduleTask, doStop, establishSharedConnection, getBeanName, getClientId, getPausedTaskCount, getPhase, getSharedConnection, initialize, isActive, isAutoStartup, isRunning, logRejectedTask, refreshSharedConnection, rescheduleTaskIfNecessary, resumePausedTasks, runningAllowed, setAutoStartup, setBeanName, setClientId, setPhase, shutdown, start, startSharedConnection, stop, stopSharedConnection`

    - ### Methods inherited from class org.springframework.jms.support.destination.JmsDestinationAccessor

      `getDestinationResolver, isPubSubDomain, receiveFromConsumer, resolveDestinationName, setDestinationResolver, setPubSubDomain`

    - ### Methods inherited from class org.springframework.jms.support.JmsAccessor

      `convertJmsAccessException, createConnection, createSession, getConnectionFactory, getSessionAcknowledgeMode, isClientAcknowledge, isSessionTransacted, obtainConnectionFactory, setConnectionFactory, setSessionAcknowledgeMode, setSessionAcknowledgeModeName, setSessionTransacted`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

    - ### Methods inherited from interface org.springframework.jms.listener.MessageListenerContainer

      `getDestinationResolver, isPubSubDomain`

    - ### Methods inherited from interface org.springframework.context.SmartLifecycle

      `getPhase, isAutoStartup, stop`

    - ### Methods inherited from interface org.springframework.context.Lifecycle

      `isRunning, start, stop`

- - ### Constructor Detail

    - #### SimpleMessageListenerContainer

          public SimpleMessageListenerContainer()

  - ### Method Detail

    - #### setConnectLazily

          public void setConnectLazily(boolean connectLazily)

      Specify whether to connect lazily, i.e. whether to establish the JMS Connection and the corresponding Sessions and MessageConsumers as late as possible - in the start phase of this container.

      Default is "false": connecting early, i.e. during the bean initialization phase. Set this flag to "true" in order to switch to lazy connecting if your target broker is likely to not have started up yet and you prefer to not even try a connection.

      See Also:
        `AbstractJmsListeningContainer.start()`, `AbstractJmsListeningContainer.initialize()`

    - #### setRecoverOnException

          public void setRecoverOnException(boolean recoverOnException)

      Specify whether to explicitly recover the shared JMS Connection and the associated Sessions and MessageConsumers whenever a JMSException is reported.

      Default is "true": refreshing the shared connection and re-initializing the consumers whenever the connection propagates an exception to its listener. Set this flag to "false" in order to rely on automatic recovery within the provider, holding on to the existing connection and consumer handles.

      Since:
        5.1.8
      See Also:
        `onException(JMSException)`, `Connection.setExceptionListener(javax.jms.ExceptionListener)`

    - #### setConcurrency

          public void setConcurrency(String concurrency)

      Specify concurrency limits via a "lower-upper" String, e.g. "5-10", or a simple upper limit String, e.g. "10".

      This listener container will always hold on to the maximum number of consumers `setConcurrentConsumers(int)` since it is unable to scale.

      This property is primarily supported for configuration compatibility with `DefaultMessageListenerContainer`. For this local listener container, generally use `setConcurrentConsumers(int)` instead.

      Specified by:
        `setConcurrency` in class `AbstractMessageListenerContainer`

    - #### setConcurrentConsumers

          public void setConcurrentConsumers(int concurrentConsumers)

      Specify the number of concurrent consumers to create. Default is 1.

      Raising the number of concurrent consumers is recommendable in order to scale the consumption of messages coming in from a queue. However, note that any ordering guarantees are lost once multiple consumers are registered. In general, stick with 1 consumer for low-volume queues.

      Do not raise the number of concurrent consumers for a topic. This would lead to concurrent consumption of the same message, which is hardly ever desirable.

    - #### setTaskExecutor

          public void setTaskExecutor(Executor taskExecutor)

      Set the Spring TaskExecutor to use for executing the listener once a message has been received by the provider.

      Default is none, that is, to run in the JMS provider's own receive thread, blocking the provider's receive endpoint while executing the listener.

      Specify a TaskExecutor for executing the listener in a different thread, rather than blocking the JMS provider, usually integrating with an existing thread pool. This allows to keep the number of concurrent consumers low (1) while still processing messages concurrently (decoupled from receiving!).

      NOTE: Specifying a TaskExecutor for listener execution affects acknowledgement semantics. Messages will then always get acknowledged before listener execution, with the underlying Session immediately reused for receiving the next message. Using this in combination with a transacted session or with client acknowledgement will lead to unspecified results!

      NOTE: Concurrent listener execution via a TaskExecutor will lead to concurrent processing of messages that have been received by the same underlying Session. As a consequence, it is not recommended to use this setting with a `SessionAwareMessageListener`, at least not if the latter performs actual work on the given Session. A standard `MessageListener` will work fine, in general.

      See Also:
        `setConcurrentConsumers(int)`, `SimpleAsyncTaskExecutor`, `WorkManagerTaskExecutor`

    - #### validateConfiguration

          protected void validateConfiguration()

      Description copied from class: `AbstractJmsListeningContainer`
      Validate the configuration of this container.

      The default implementation is empty. To be overridden in subclasses.

      Overrides:
        `validateConfiguration` in class `AbstractMessageListenerContainer`

    - #### sharedConnectionEnabled

          protected final boolean sharedConnectionEnabled()

      Always use a shared JMS Connection.
      Specified by:
        `sharedConnectionEnabled` in class `AbstractJmsListeningContainer`
      See Also:
        `AbstractJmsListeningContainer.getSharedConnection()`

    - #### doInitialize

          protected void doInitialize()
                               throws JMSException

      Creates the specified number of concurrent consumers, in the form of a JMS Session plus associated MessageConsumer.
      Specified by:
        `doInitialize` in class `AbstractJmsListeningContainer`
      Throws:
        `JMSException` - if registration failed
      See Also:
        `createListenerConsumer(javax.jms.Session)`

    - #### doStart

          protected void doStart()
                          throws JMSException

      Re-initializes this container's JMS message consumers, if not initialized already.
      Overrides:
        `doStart` in class `AbstractJmsListeningContainer`
      Throws:
        `JMSException` - if thrown by JMS API methods
      See Also:
        `AbstractJmsListeningContainer.startSharedConnection()`

    - #### prepareSharedConnection

          protected void prepareSharedConnection(Connection connection)
                                          throws JMSException

      Registers this listener container as JMS ExceptionListener on the shared connection.
      Overrides:
        `prepareSharedConnection` in class `AbstractJmsListeningContainer`
      Parameters:
        `connection` - the Connection to prepare
      Throws:
        `JMSException` - if the preparation efforts failed
      See Also:
        `AbstractJmsListeningContainer.getClientId()`

    - #### onException

          public void onException(JMSException ex)

      JMS ExceptionListener implementation, invoked by the JMS provider in case of connection failures. Re-initializes this listener container's shared connection and its sessions and consumers, if necessary.
      Specified by:
        `onException` in interface `ExceptionListener`
      Parameters:
        `ex` - the reported connection exception
      See Also:
        `setRecoverOnException(boolean)`, `AbstractJmsListeningContainer.refreshSharedConnection()`, `initializeConsumers()`

    - #### initializeConsumers

          protected void initializeConsumers()
                                      throws JMSException

      Initialize the JMS Sessions and MessageConsumers for this container.
      Throws:
        `JMSException` - in case of setup failure

    - #### createListenerConsumer

          protected MessageConsumer createListenerConsumer(Session session)
                                                    throws JMSException

      Create a MessageConsumer for the given JMS Session, registering a MessageListener for the specified listener.
      Parameters:
        `session` - the JMS Session to work on
      Returns:
        the MessageConsumer
      Throws:
        `JMSException` - if thrown by JMS methods
      See Also:
        `AbstractMessageListenerContainer.executeListener(javax.jms.Session, javax.jms.Message)`

    - #### processMessage

          protected void processMessage(Message message,
                                        Session session)

      Process a message received from the provider.

      Executes the listener, exposing the current JMS Session as thread-bound resource (if "exposeListenerSession" is "true").

      Parameters:
        `message` - the received JMS Message
        `session` - the JMS Session to operate on
      See Also:
        `AbstractMessageListenerContainer.executeListener(javax.jms.Session, javax.jms.Message)`, `AbstractMessageListenerContainer.setExposeListenerSession(boolean)`

    - #### doShutdown

          protected void doShutdown()
                             throws JMSException

      Destroy the registered JMS Sessions and associated MessageConsumers.
      Specified by:
        `doShutdown` in class `AbstractJmsListeningContainer`
      Throws:
        `JMSException` - if shutdown failed
      See Also:
        `AbstractJmsListeningContainer.shutdown()`