1. 前言
基于JMS标准的消息中间件实现的产品有很多,JBossMQ、ActiveMQ、OpenMQ、OpenJMS等等,最常用的还是apache的ActiveMQ。有时也使用Sun的OpenMQ。在官网http://mq.java.net/处可以下载。Open Message Queue是Sun Java System Message Queue的一个开源版本。Open message queue是一个企业级,可升级,非常成熟的消息服务器。它为面向消息的系统集成提供一套完整的JMS(Java Message Service )实现。由于Open MQ源自Sun的Java Message Queue,所以其具有Java System Message Queue拥有的所有特性,功能和性能。
2. 环境配置
下载后将相关的jar拷贝到项目的classpath下面。笔者在此为了安全起见,引入了很多jar包,将语言包都引入了。各位读者可以因地制宜。
以下是引入jar包的列表
- lib/openmqjar/common-message.jar
- lib/openmqjar/fscontext.jar
- lib/openmqjar/grizzly.jar
- lib/openmqjar/imq_de.jar
- lib/openmqjar/imq_es.jar
- lib/openmqjar/imq_fr.jar
- lib/openmqjar/imq_it.jar
- lib/openmqjar/imq_ja.jar
- lib/openmqjar/imq_ko.jar
- lib/openmqjar/imq_pt_BR.jar
- lib/openmqjar/imq_zh_CN.jar
- lib/openmqjar/imq_zh_TW.jar
- lib/openmqjar/imq.jar
- lib/openmqjar/imqadmin.jar
- lib/openmqjar/imqbridgemgr.jar
- lib/openmqjar/imqbroker.jar
- lib/openmqjar/imqjmsbridge.jar
- lib/openmqjar/imqjmsra.rar
- lib/openmqjar/imqjmx_de.jar
- lib/openmqjar/imqjmx_es.jar
- lib/openmqjar/imqjmx_fr.jar
- lib/openmqjar/imqjmx_it.jar
- lib/openmqjar/imqjmx_ja.jar
- lib/openmqjar/imqjmx_ko.jar
- lib/openmqjar/imqjmx_pt_BR.jar
- lib/openmqjar/imqjmx_zh_CN.jar
- lib/openmqjar/imqjmx_zh_TW.jar
- lib/openmqjar/imqjmx.jar
- lib/openmqjar/imql10n_server_de.jar
- lib/openmqjar/imql10n_server_es.jar
- lib/openmqjar/imql10n_server_fr.jar
- lib/openmqjar/imql10n_server_it.jar
- lib/openmqjar/imql10n_server_ja.jar
- lib/openmqjar/imql10n_server_ko.jar
- lib/openmqjar/imql10n_server_pt_BR.jar
- lib/openmqjar/imql10n_server_zh_CN.jar
- lib/openmqjar/imql10n_server_zh_TW.jar
- lib/openmqjar/imqservlet.jar
- lib/openmqjar/imqstomp.jar
- lib/openmqjar/imqutil.jar
- lib/openmqjar/imqxm.jar
- lib/openmqjar/jaxm-api.jar
- lib/openmqjar/jhall.jar
- lib/openmqjar/jms.jar
- lib/openmqjar/jta.jar
- lib/openmqjar/protobuf-2.3.0.jar
3. 之后项目加入Spring的相关jar包。
增加Spring配置文件内容如下:
- <?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-2.5.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-2.5.xsd"
- default-autowire="byName">
- <!--消息连接工厂-->
- <bean id="connectionfactoryfactory"
- class="message.listener.OpenMqConnectionFactory">
- <property name="properties">
- <props>
- <prop key="imqAddressList">127.0.0.1:7676</prop>
- <prop key="imqDefaultUsername">admin</prop>
- <prop key="imqDefaultPassword">admin</prop>
- <prop key="imqReconnectEnabled">true</prop>
- <prop key="imqReconnectAttempts">3</prop>
- <prop key="imqReconnectInterval">5000</prop>
- <prop key="imqAddressListBehavior">RANDOM</prop>
- </props>
- </property>
- </bean>
- <bean id="mqConnectionFactory" factory-bean="connectionfactoryfactory"
- factory-method="createConnectionFactory" />
- <!--设置广发消息目的-->
- <bean id="updateLocalRouteMap" class="com.sun.messaging.Topic">
- <constructor-arg type="java.lang.String" value="mytopic" />
- </bean>
- <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
- <property name="connectionFactory" ref="mqConnectionFactory" />
- <property name="defaultDestination" ref="updateLocalRouteMap" />
- <property name="receiveTimeout" value="20000" />
- </bean>
- <!--消息监听器-->
- <bean id="messageListener1"
- class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
- <constructor-arg>
- <bean
- class="message.listener.JMSMessageListener" />
- </constructor-arg>
- <property name="defaultListenerMethod" value="receive" />
- <property name="messageConverter">
- <null />
- </property>
- </bean>
- <!—实际的消息监消费者配置-->
- <bean id="consumercontainer"
- class="org.springframework.jms.listener.DefaultMessageListenerContainer">
- <property name="connectionFactory" ref="mqConnectionFactory" />
- <property name="destination" ref="updateLocalRouteMap" />
- <property name="messageListener" ref="messageListener1" />
- <property name="transactionTimeout" value="180000" />
- <property name="receiveTimeout" value="180000" />
- <property name="sessionTransacted" value="true" />
- </bean>
- </beans>
4. 消息监听器
类代码如下
- /**
- * JMS消息消费者。
- * 接收JMS消息后获得router想要的消息后,调用router接口更新本地缓存
- * @author liuyan
- *
- */
- public class JMSMessageListener implements MessageListener {
- private Logger log = Logger.getLogger(JMSMessageListener.class.getName());
- /**
- * 接收JMS消息后的业务处理
- */
- public void onMessage(Message message) {
- log.info("接收消息……");
- byte[] byteMessage = JMSByteConverterUtil
- .ConverterMessageToBttes(message);
- try {
- log.info("将转型成实体对象……");
- //……………………………………………………
- }
- } catch (InvalidProtocolBufferException e) {
- log.error("JMS异常" + e.getMessage());
- e.printStackTrace();
- } catch (Exception e) {
- log.error("其他异常" + e.getMessage());
- e.printStackTrace();
- }
- }
- }
因为一些原因此处就不给出完整代码了~~~反正是获取一个字节流后,转成对象,直接从对象中获取想要的信息。转成对象的辅助类如下
- /**
- * 对获得的消息对象进行转型
- * @author liuyan
- */
- public class JMSByteConverterUtil {
- private static Logger log = Logger.getLogger(JMSMessageListener.class
- .getName());
- /**
- * 对获得的消息对象进行转型
- * @param message
- * @return
- */
- public static byte[] ConverterMessageToBttes(Message message) {
- if (message == null) {
- log.error("消息对象为空……");
- return null;
- } else if (message instanceof BytesMessage) {
- log.debug("消息强制转型BytesMessage");
- BytesMessage bytesMessage = (BytesMessage) message;
- byte[] messageBytes;
- try {
- log.debug("建立空的消息二进制数组");
- messageBytes = new byte[(int) bytesMessage.getBodyLength()];
- log.debug("往二进制数组中写进二进制信息");
- bytesMessage.readBytes(messageBytes);
- log.debug("messageBytes.length=" + messageBytes.length);
- return messageBytes;
- } catch (JMSException e) {
- log.error("JMS错误:" + e.getMessage());
- e.printStackTrace();
- return null;
- }
- }else{
- log.error("消息对象不能正确转型");
- return null;
- }
- }
- }
5. 启动消息监听器
开启OpenMQ的服务,启动{OpenMQ_HOME}\mq\bin\下的imqcmd.exe命令
启动消息消费者很简单,代码如下
- public class MessageConsumer {
- /**
- * @param args
- */
- public static void main(String[] args) {
- ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
- new String[] { "classpath:/spring/applicationContext-openmq-jms.xml" });
- System.out.println(applicationContext.getId());
- }
- }
6. 消息发送者
启动消息消费者服务后,写一个测试类测试一下消息的,代码如下
- public class MessageSender {
- /**
- * @param args
- * @throws JMSException
- */
- public static void main(String[] args) throws JMSException {
- ConnectionFactory myConnFactory;
- myConnFactory = new com.sun.messaging.ConnectionFactory();
- myConnFactory.setProperty(ConnectionConfiguration.imqAddressList,
- "mq://127.0.0.1:7676");
- myConnFactory.setProperty(ConnectionConfiguration.imqReconnectEnabled,
- "true");
- Connection myConn = myConnFactory.createConnection();
- myConn.start();
- // Step 4:
- // Create a session within the connection.
- Session mySess = myConn.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Topic myTopic = new com.sun.messaging.Topic("testmq");// .Queue("testmq");
- MessageProducer myMsgProducer = mySess.createProducer(myTopic);
- ObjectMessage objectMessage = mySess.createObjectMessage();
- RouterMessageBean routerMessageBean = new RouterMessageBean();
- routerMessageBean.setDbName("mysql-test");
- routerMessageBean.setUserName("liuyan");
- routerMessageBean.setMaster(null);
- routerMessageBean.setSlave(null);
- objectMessage.setObject(routerMessageBean);
- BytesMessage bytesMessage = mySess.createBytesMessage();
- bytesMessage.writeUTF("the message is 消息内容!");
- myMsgProducer.send(bytesMessage);
- System.out.println("测试发送JMS消息");
- mySess.close();
- myConn.close();
- }
- }