Spring JMS Templateの簡単なサンプル
先日はJMSによるRMIを見ましたが、ここではもう少し低レベルなJMSのメッセージ送受信について見ていきます。使用ライブラリは前回と同一です。
使用ライブラリ
Spring関連
- spring.jar(2.5.5)
- spring-test.jar(2.5.5)
ActiveMQ関連
- activemq-all-5.2.0.jar
- xbean-spring-3.4.jar
- junit-4.7.jar
メッセージ送信側
JMSメッセージの送受信には JmsTemplate が用意されています。ここではメッセージの送信に template.send を使用しています。送信するメッセージはテキストメッセージとしています。
package etc9; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.Session; import javax.jms.TextMessage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.core.MessageCreator; public class JmsMessageProducer { @Autowired private JmsTemplate template; public void simpleSend(final String msg) { template.send( new MessageCreator() { public Message createMessage(Session session) throws JMSException { TextMessage message = session.createTextMessage("Text Message from Producer:" + msg); return message; } }); } }
メッセージ受信側
JmsMessageConsumerなどを用意して JmsTemplate を使うことで MDPs(message-driven POJOs) ではない普通のJMSメッセージのやり取りもできます。が、ここでは MessageListener を実装したリスナーを用意し、メッセージドリブンで処理が行われるようにします。といっても実装は onMessage() に処理を書くだけです。
package etc9; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.TextMessage; public class JmsMessageListener implements MessageListener { public void onMessage(Message message) { try { if (message instanceof TextMessage) { TextMessage tm = (TextMessage)message; String msg = tm.getText(); System.out.println(msg); } } catch (JMSException e) { e.printStackTrace(); } } }
テストケース
テストケースを以下のようにします。JmsMessageProducer からメッセージ"hoge"を送信するだけです。受信側はメッセージの到着で自動的に処理が行われます。
package etc9; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import etc9.JmsMessageProducer; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration public class JmsMessageListenerTest { @Autowired public JmsMessageProducer jmsMessageProducer; @Test public void testMessage() throws Exception { jmsMessageProducer.simpleSend("hoge"); } }
テストケース用Spring設定
JmsMessageListenerTest-context.xml をテストケースと同じディレクトリに用意します。全文は末尾に記載します。
ActiveMQの設定
ActiveMQの設定は前回と同様に組み込みモードとして定義しています。
<!-- create an embedded ActiveMQ Broker --> <amq:broker id="broker" useJmx="false" persistent="false"> <amq:transportConnectors> <amq:transportConnector uri="tcp://localhost:0" /> </amq:transportConnectors> </amq:broker> <!-- ActiveMQ Destination --> <amq:queue id="destination" physicalName="jms.test" /> <!-- embedded モードでの MessageBroker を使用 --> <amq:connectionFactory id="jmsFactory" brokerURL="vm://localhost" />
JMS Producer 側の設定
<!-- JMS Producer Configuration --> <bean id="jmsProducerConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory" depends-on="broker" p:targetConnectionFactory-ref="jmsFactory" /> <bean id="jmsProducerTemplate" class="org.springframework.jms.core.JmsTemplate" p:connectionFactory-ref="jmsProducerConnectionFactory" p:defaultDestination-ref="destination" /> <bean id="jmsMessageProducer" class="etc9.JmsMessageProducer" />
JMS Consumer 側の設定
<!-- JMS Consumer Configuration --> <bean id="jmsMessageListener" class="etc9.JmsMessageListener" /> <bean id="jmsConsumerConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory" depends-on="broker" p:targetConnectionFactory-ref="jmsFactory" /> <!-- JMS Namespace によるリスナーコンテナの設定 --> <jms:listener-container container-type="default" connection-factory="jmsConsumerConnectionFactory" acknowledge="auto"> <jms:listener destination="jms.test" ref="jmsMessageListener" /> </jms:listener-container>
実行結果
コンソールに以下の出力が得られれば成功です。
Text Message from Producer:hoge
JmsMessageListenerTest-context.xml 全文
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:jms="http://www.springframework.org/schema/jms" xmlns:amq="http://activemq.apache.org/schema/core" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> <amq:broker id="broker" useJmx="false" persistent="false"> <amq:transportConnectors> <amq:transportConnector uri="tcp://localhost:0" /> </amq:transportConnectors> </amq:broker> <amq:queue id="destination" physicalName="jms.test" /> <amq:connectionFactory id="jmsFactory" brokerURL="vm://localhost" /> <bean id="jmsProducerConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory" depends-on="broker" p:targetConnectionFactory-ref="jmsFactory" /> <bean id="jmsProducerTemplate" class="org.springframework.jms.core.JmsTemplate" p:connectionFactory-ref="jmsProducerConnectionFactory" p:defaultDestination-ref="destination" /> <bean id="jmsMessageProducer" class="etc9.JmsMessageProducer" /> <bean id="jmsMessageListener" class="etc9.JmsMessageListener" /> <bean id="jmsConsumerConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory" depends-on="broker" p:targetConnectionFactory-ref="jmsFactory" /> <jms:listener-container container-type="default" connection-factory="jmsConsumerConnectionFactory" acknowledge="auto"> <jms:listener destination="jms.test" ref="jmsMessageListener" /> </jms:listener-container> </beans>
JMS ネームスペースなど使用しない場合
JMS ネームスペースなどを使用しない JmsMessageListenerTest-context.xmlの例です。動作的には同じです・・
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:amq="http://activemq.apache.org/schema/core" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> <amq:broker id="broker" useJmx="false" persistent="false"> <amq:transportConnectors> <amq:transportConnector uri="tcp://localhost:0" /> </amq:transportConnectors> </amq:broker> <amq:queue id="destination" physicalName="jms.test" /> <amq:connectionFactory id="jmsFactory" brokerURL="vm://localhost" /> <bean id="jmsMessageProducer" class="etc9.JmsMessageProducer" /> <bean id="jmsProducerConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory"> <property name="targetConnectionFactory"><ref local="jmsFactory" /></property> </bean> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="jmsProducerConnectionFactory" /> <property name="defaultDestination" ref="destination" /> </bean> <bean id="jmsMessageListener" class="etc9.JmsMessageListener" /> <bean id="jmsConsumerConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory"> <property name="targetConnectionFactory" ref="jmsFactory" /> </bean> <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="connectionFactory" ref="jmsConsumerConnectionFactory"/> <property name="destinationName" value="jms.test" /> <property name="messageListener" ref="jmsMessageListener" /> </bean> </beans>