用Spring發送和接受JMS消息的一個小例子
摘要 和通過直接使用JMS的API相比,大大簡化了代碼的編寫。
Spring提供的JmsTemplate對原生的JMS API進行了一層薄薄的封裝,使用起來非常的方便。
我使用的JMS消息代理插件是Apache的ActiveMQ,建議安裝最新版本,因為我之前安裝老版本,各種不兼容,各種bug,最新版的activemq-all-5.9.1.jar包里面已經有了slf4j.impl包,之前就是被這個坑了...把這個jar包加到lib目錄下面,就不會有各種ClassNotFound異常和類沖突的bug了。
下載ActiveMQ解壓之后運行bin下面的activemq.bat就可以運行了。你可以訪問http://127.0.0.1:8161/看看服務是否正常開啟
默認賬戶密碼是admin/admin
下面這個例子是一個郵局系統,包括前后臺兩個子系統,當前臺收到一封郵件的時候,它將這封郵件傳遞給后臺,同時發送一個JMS消息給后臺子系統,提醒新的郵件。
JMS有兩種消息通信模型:
1)、point-to-point
2)、pub/sub
這里我們當然是用的第一種模型.
首先我們建立一個Mail類:
package com.apress.springrecipes.post; public class Mail { private String mailId; private String country; private double weight; public Mail() { } public Mail(String mailId, String country, double weight) { this.mailId = mailId; this.country = country; this.weight = weight; } public String getMailId() { return mailId; } public void setMailId(String mailId) { this.mailId = mailId; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } }
一個前臺子系統接口:
package com.apress.springrecipes.post; public interface FrontDesk { public void sendMail(Mail mail); }
和它的實現類:
package com.apress.springrecipes.post; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.MapMessage; import javax.jms.Message; import javax.jms.Session; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.core.MessageCreator; public class FrontDeskImpl2 implements FrontDesk { @Autowired private JmsTemplate jmsTemplate; @Autowired private Destination destination; @Override public void sendMail(final Mail mail) { jmsTemplate.send(destination,new MessageCreator() { @Override public Message createMessage(Session session) throws JMSException { MapMessage message = session.createMapMessage(); message.setString("mailId", mail.getMailId()); message.setString("country", mail.getCountry()); message.setDouble("weight", mail.getWeight()); return message; } }); } }
一個后臺子系統的接口:
package com.apress.springrecipes.post; public interface BackOffice { public Mail receiveMail(); }
和它的實現類:
package com.apress.springrecipes.post; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.MapMessage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.support.JmsUtils; public class BackOfficeImpl2 implements BackOffice { @Autowired private JmsTemplate jmsTemplate; @Autowired private Destination destination; @Override public Mail receiveMail() { MapMessage message = (MapMessage) jmsTemplate.receive(destination); try { if (message == null) { return null; } Mail mail = new Mail(); mail.setMailId(message.getString("mailId")); mail.setCountry(message.getString("country")); mail.setWeight(message.getDouble("weight")); return mail; } catch (JMSException e) { throw JmsUtils.convertJmsAccessException(e); } } }
前臺子系統的xml配置文件bean-front.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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config/> <bean id="frontDesk" class="com.apress.springrecipes.post.FrontDeskImpl2" /> <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616"/> </bean> <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg value="mail.queue" /> </bean> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="connectionFactory"/> </bean> </beans>
后臺子系統的xml配置文件bean-back.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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config /> <bean id="backOffice" class="com.apress.springrecipes.post.BackOfficeImpl2" /> <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean> <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg value="mail.queue" /> </bean> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="connectionFactory" /> <property name="receiveTimeout" value="10000" /> </bean> </beans>
兩個測試類,一個是發消息,一個是接受消息。
package com.apress.springrecipes.post; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class FrontDeskMain { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans-front.xml"); FrontDesk frontDesk = (FrontDesk) context.getBean("frontDesk"); frontDesk.sendMail(new Mail("1234","US",1.5)); } }
package com.apress.springrecipes.post; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class BackOfficeMain { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans-back.xml"); BackOffice backOffice = (BackOffice) context.getBean("backOffice"); Mail mail = backOffice.receiveMail(); System.out.println("Mail #" + mail.getMailId() + " received"); } }
運行FrontDeskMain之后,發送消息你可以簡單的通過訪問http://127.0.0.1:8161/admin/queueGraph.jsp和http://127.0.0.1:8161/admin/queues.jsp觀察發生的情況。再運行BackOfficeMain觀察這兩個頁面的變化。
來自:http://my.oschina.net/fengshuzi/blog/346303