The few pieces that I found scattered about in many places which I would recommend are:
- Use a pooled connection factory with Spring. The JMS Template is rather heavy as it opens and closes a connection every message as well as other over head. A serious waste and ActiveMQ recommends using theirs.
- With the message listener, be sure to include the destroy-method="shutdown" attribute as without it, there is no guarantee that your consumers will be terminated correctly (a problem we ran into without realizing it for a few days)
- Add maxConcurrentConsumers to increase the number of consumers to help process the messages. This will dynamically change the number of consumers based on need and has tested to be a big win for us.
Some resources:
http://activemq.apache.org/
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ch21.html
<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="${activemq.destination.name}">
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="jmsFactory">
<property name="defaultDestination" ref="pruneDestination">
</bean>
<bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory" method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${activemq.broker.url}">
</bean>
</property>
</bean>
<bean id="messageListener" class="some.path.to.a.MessageListener">
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer" method="shutdown">
<property name="connectionFactory" ref="jmsFactory">
<property name="destination" ref="destination">
<property name="messageListener" ref="messageListener">
<property name="maxConcurrentConsumers" value="5">
</bean>