org.springframework.jms.listener
Class SimpleMessageListenerContainer

java.lang.Object
  extended by org.springframework.jms.support.JmsAccessor
      extended by org.springframework.jms.support.destination.JmsDestinationAccessor
          extended by org.springframework.jms.listener.AbstractJmsListeningContainer
              extended by org.springframework.jms.listener.AbstractMessageListenerContainer
                  extended by org.springframework.jms.listener.SimpleMessageListenerContainer
All Implemented Interfaces:
ExceptionListener, Aware, BeanNameAware, DisposableBean, InitializingBean, Lifecycle, Phased, SmartLifecycle
Direct Known Subclasses:
SimpleMessageListenerContainer102

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.

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.JmsAccessor
logger
 
Constructor Summary
SimpleMessageListenerContainer()
           
 
Method Summary
protected  MessageConsumer createConsumer(Session session, Destination destination)
          Create a JMS MessageConsumer for the given Session and Destination.
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.
protected  boolean isPubSubNoLocal()
          Return whether to inhibit the delivery of messages published by its own connection.
 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 setPubSubNoLocal(boolean pubSubNoLocal)
          Set whether to inhibit the delivery of messages published by its own connection.
 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, doExecuteListener, doInvokeListener, doInvokeListener, executeListener, getDefaultSubscriptionName, getDestination, getDestinationDescription, getDestinationName, getDurableSubscriptionName, getExceptionListener, getMessageListener, getMessageSelector, handleListenerException, invokeErrorHandler, invokeExceptionListener, invokeListener, isAcceptMessagesWhileStopping, isExposeListenerSession, isSessionLocallyTransacted, isSubscriptionDurable, rollbackIfNecessary, rollbackOnExceptionIfNecessary, setAcceptMessagesWhileStopping, setDestination, setDestinationName, setDurableSubscriptionName, setErrorHandler, setExceptionListener, setExposeListenerSession, setMessageListener, setMessageSelector, setSubscriptionDurable
 
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, stop, stopSharedConnection
 
Methods inherited from class org.springframework.jms.support.destination.JmsDestinationAccessor
getDestinationResolver, isPubSubDomain, resolveDestinationName, setDestinationResolver, setPubSubDomain
 
Methods inherited from class org.springframework.jms.support.JmsAccessor
convertJmsAccessException, createConnection, createSession, getConnectionFactory, getSessionAcknowledgeMode, isClientAcknowledge, isSessionTransacted, setConnectionFactory, setSessionAcknowledgeMode, setSessionAcknowledgeModeName, setSessionTransacted
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

SimpleMessageListenerContainer

public SimpleMessageListenerContainer()
Method Detail

setPubSubNoLocal

public void setPubSubNoLocal(boolean pubSubNoLocal)
Set whether to inhibit the delivery of messages published by its own connection. Default is "false".

See Also:
TopicSession.createSubscriber(javax.jms.Topic, String, boolean)

isPubSubNoLocal

protected boolean isPubSubNoLocal()
Return whether to inhibit the delivery of messages published by its own connection.


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.


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.

Specified by:
onException in interface ExceptionListener
Parameters:
ex - the reported connection exception

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()

createConsumer

protected MessageConsumer createConsumer(Session session,
                                         Destination destination)
                                  throws JMSException
Create a JMS MessageConsumer for the given Session and Destination.

This implementation uses JMS 1.1 API.

Parameters:
session - the JMS Session to create a MessageConsumer for
destination - the JMS Destination to create a MessageConsumer for
Returns:
the new JMS MessageConsumer
Throws:
JMSException - if thrown by JMS API methods