Spring with ActiveMQ
Spring provides an abstraction for dealing with JMS. Specifically for adding and removing messages to a JMS queue and for browsing a queue. I found the documentation for removing messages from a queue, i.e., consuming messages in the context of a servlet to be somewhat scant. Here is what I had to do configure Spring to send and consume messages.
Setup the queue
Using the Spring applicationContext.xml configuration mechanism, you’ll need to specify beans to setup the connection factory (including the location of the ActiveMQ broker), the jsm template and the queue name. All of the beans described here are defined in the applicationContext.xml file (which must be in the classpath).
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL"> <value>tcp://localhost:61616</value> </property></bean><bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory"> <ref local="connectionFactory"/> </property></bean><bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg index="0"> <value>input.queue</value> </constructor-arg></bean>
Somewhere in your initialization code, you’ll need to get hold of a Spring application context and read the jms template and the queue (destination). You may be able to use injection to add these beans to what ever class you are using to send the message. But in case you cannot, you must explicitly get hold of the application context and read these beans (here I’m assuming that you’re writing a servlet and hence the use of the WebApplicationContextUtils).
ApplicationContext ctx = WebApplicationContextUtils .getRequiredWebApplicationContext(sc.getServletContext());JmsTemplate template = (JmsTemplate) ctx.getBean("jmsTemplate");Queue inputQueue = (Queue) ctx.getBean("destination");
Send Message
private void sendMessage(final MyMessage myMessage) { template.send(inputQueue, new MessageCreator() { public Message createMessage(Session session) throws JMSException { Message msg = session.createMessage(); // set message properties return msg; } });}
Consume Message
Configure the message consumer bean. Here we are creating 5 concurrent consumers threads. Spring will manage the creation of the consumers.
<bean id="messageListener" class="com.mydomain.InputQueueListener" /> <!-- and this is the message listener container --><bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="concurrentConsumers" value="5"/> <property name="connectionFactory" ref="connectionFactory" /> <property name="destination" ref="destination" /> <property name="messageListener" ref="messageListener" /></bean>
Create a consumer class. Its onMessage method will be called by each consumer thread.
public class InputQueueListener implements MessageListener { public void onMessage(Message message) { //process message }}
I’m still searching for a good way to create a browser. The ActiveMQ admin sample uses a SessionPool, it is not clear why they have created a sample SessionPool for the admin console when there is a real SessionPool in the ActiveMQ core.