MessageConsumer.receive()
calls that also allow for transactional reception of messages (registering them with XA transactions). Designed to work in a native JMS environment as well as in a J2EE environment, with only minimal differences in configuration. NOTE: This class requires a JMS 1.1+ provider, because it builds on the domain-independent API. Use the {@link DefaultMessageListenerContainer102}subclass for a JMS 1.0.2 provider, e.g. when running on a J2EE 1.3 server.
This is a simple but nevertheless powerful form of message listener container. On startup, it obtains a fixed number of JMS Sessions to invoke the listener, and optionally allows for dynamic adaptation at runtime (up until a maximum number). Like {@link SimpleMessageListenerContainer}, its main advantage is its low level of runtime complexity, in particular the minimal requirements on the JMS provider: Not even the JMS ServerSessionPool facility is required. Beyond that, it is fully self-recovering in case of the broker being temporarily unavailable, and allows for stops/restarts as well as runtime changes to its configuration.
Actual MessageListener execution happens in asynchronous work units which are created through Spring's {@link org.springframework.core.task.TaskExecutor}abstraction. By default, the specified number of invoker tasks will be created on startup, according to the {@link #setConcurrentConsumers "concurrentConsumers"}setting. Specify an alternative TaskExecutor to integrate with an existing thread pool facility (such as a J2EE server's), for example using a {@link org.springframework.scheduling.commonj.WorkManagerTaskExecutor CommonJ WorkManager}. With a native JMS setup, each of those listener threads is going to use a cached JMS Session and MessageConsumer (only refreshed in case of failure), using the JMS provider's resources as efficiently as possible.
Message reception and listener execution can automatically be wrapped in transactions through passing a Spring {@link org.springframework.transaction.PlatformTransactionManager} into the{@link #setTransactionManager "transactionManager"} property. This will usuallybe a {@link org.springframework.transaction.jta.JtaTransactionManager} in aJ2EE enviroment, in combination with a JTA-aware JMS ConnectionFactory obtained from JNDI (check your J2EE server's documentation). Note that this listener container will automatically reobtain all JMS handles for each transaction in case of an external transaction manager specified, for compatibility with all J2EE servers (in particular JBoss). This non-caching behavior can be overridden through the {@link #setCacheLevel "cacheLevel"} /{@link #setCacheLevelName "cacheLevelName"} property, enforcing cachingof the Connection (or also Session and MessageConsumer) even in case of an external transaction manager being involved.
Dynamic scaling of the number of concurrent invokers can be activated through specifying a {@link #setMaxConcurrentConsumers "maxConcurrentConsumers"}value that is higher than the {@link #setConcurrentConsumers "concurrentConsumers"}value. Since the latter's default is 1, you can also simply specify a "maxConcurrentConsumers" of e.g. 5, which will lead to dynamic scaling up to 5 concurrent consumers in case of increasing message load, as well as dynamic shrinking back to the standard number of consumers once the load decreases. Consider adapting the {@link #setIdleTaskExecutionLimit "idleTaskExecutionLimit"}setting to control the lifespan of each new task, to avoid frequent scaling up and down, in particular if the ConnectionFactory does not pool JMS Sessions and/or the TaskExecutor does not pool threads (check your configuration!). Note that dynamic scaling only really makes sense for a queue in the first place; for a topic, you will typically stick with the default number of 1 consumer, else you'd receive the same message multiple times on the same node.
It is strongly recommended to either set {@link #setSessionTransacted "sessionTransacted"} to "true" or specify an external {@link #setTransactionManager "transactionManager"}. See the {@link AbstractMessageListenerContainer}javadoc for details on acknowledge modes and native transaction options, as well as the {@link AbstractPollingMessageListenerContainer} javadocfor details on configuring an external transaction manager. @author Juergen Hoeller @since 2.0 @see #setTransactionManager @see #setCacheLevel @see javax.jms.MessageConsumer#receive(long) @see SimpleMessageListenerContainer @see org.springframework.jms.listener.endpoint.JmsMessageEndpointManager
|
|