Java中间件JMS(四)之ActiveMQ整合spring之类转换

简介:
+关注继续查看

原文链接:http://blog.csdn.net/dwc_fly/article/details/11096071

前几章都是直接发送MapMessage类型的数据,拿前面的例子来讲,如果生产者发送的是TextMessage,消费者也是必须TextMessage;如果我们自己要发送的数据不是TextMessage类型,而消费者还是TextMessage的,那该怎么办?难道每次接受后都要增加一个转换方法么?其实spring早就考虑到这种情况了。转化器在很多组件中都是必不缺少的东西Spring的MessageConverter接口提供了对消息转换的支持。


1、转换类的相关代码POJO

新建一个类MsgPoJo,就是一个简单的Pojo类。具体代码如下:

  1. package jms.mq.spring;  

  2. import java.io.Serializable;  

  3. publicclass MsgPoJo implements Serializable{  

  4. private String id;  

  5. private String text;  

  6. public String getId() {  

  7. return id;  

  8.    }  

  9. publicvoid setId(String id) {  

  10. this.id = id;  

  11.    }  

  12. public String getText() {  

  13. return text;  

  14.    }  

  15. publicvoid setText(String text) {  

  16. this.text = text;  

  17.    }    

  18. }  


2.转换类的实现

新建一个类MsgConverter.java,实现MessageConverter接口。生成的代码如下


  1. package jms.mq.spring;  

  2. import javax.jms.JMSException;  

  3. import javax.jms.Message;  

  4. import javax.jms.Session;  

  5. import javax.jms.TextMessage;  

  6. import org.springframework.jms.support.converter.MessageConversionException;  

  7. import org.springframework.jms.support.converter.MessageConverter;  

  8. publicclass MsgConverter implements MessageConverter{  

  9. @Override

  10. public Object fromMessage(Message message) throws JMSException,  

  11.    MessageConversionException {  

  12. if (!(message instanceof TextMessage)) {  

  13. thrownew MessageConversionException("Message is not TextMessage");  

  14.        }  

  15.        System.out.println("--转换接收的消息--");  

  16.        TextMessage textMessage = (TextMessage) message;  

  17.        MsgPoJo msgPojo = new MsgPoJo();  

  18.        String[] texts=textMessage.getText().split(",");  

  19.        msgPojo.setId(texts[0]);  

  20.        msgPojo.setText(texts[1]);  

  21. return msgPojo;  

  22.    }  

  23. @Override

  24. public Message toMessage(Object object, Session session) throws JMSException,  

  25.    MessageConversionException {  

  26. if (!(object instanceof MsgPoJo)) {  

  27. thrownew MessageConversionException("obj is not MsgPojo");  

  28.        }  

  29.        System.out.println("--转换发送的消息--");  

  30.        MsgPoJo msgPojo = (MsgPoJo) object;  

  31.        TextMessage textMessage = session.createTextMessage();  

  32.        textMessage.setText(msgPojo.getId()+","+msgPojo.getText());  

  33. return  textMessage;  

  34.    }  

  35. }  



代码很简单就是做些转换,有fromMessage和toMessage两个方法,真好对应发送转换toMessage和接受转换fromMessage。此时,发送和接收消息要换成template.convertAndSend(message);template.receiveAndConvert()。接下来我做一些配置,让spring知道我们的转换类。修改applicationContext.xml中jms模版配置的代码,修改后的代码如下:

  1. <!-- 类转换 -->

  2. <beanid="msgConverter"class="jms.mq.spring.MsgConverter"></bean>

  3. <!-- 配置Jms模板 -->

  4. <beanid="jmsQueueTemplate"class="org.springframework.jms.core.JmsTemplate">

  5. <propertyname="connectionFactory"ref="connectionFactory"/>

  6. <propertyname="defaultDestination"ref="queueDest"/>

  7. <!--<property name="receiveTimeout" value="10000" /> -->

  8. <!-- 类转换 -->

  9. <propertyname="messageConverter"ref="msgConverter"></property>

  10. </bean>

注意:如果你有队列监听容器配置,配置jmsQueueTemplate和jmsTopicTemplate可能与队列容器配置冲突。

3、业务相关代码和配置

在QueueProducerService.java增加convertAndSend()方法并在其实现类中实现,实现类的代码如下:


  1. package jms.mq.spring;  

  2. import java.util.Date;  

  3. import javax.jms.Destination;  

  4. import javax.jms.JMSException;  

  5. import javax.jms.Message;  

  6. import javax.jms.Session;  

  7. import javax.jms.TextMessage;  

  8. import org.springframework.jms.core.JmsTemplate;  

  9. import org.springframework.jms.core.MessageCreator;  

  10. publicclass QueueProducerService{  

  11.    JmsTemplate jmsTemplate;  

  12.    Destination destination;  

  13. publicvoid send() {  

  14.        MessageCreator messageCreator = new MessageCreator() {  

  15. public Message createMessage(Session session) throws JMSException {  

  16.                TextMessage message = session.createTextMessage();  

  17.                message.setText("QueueProducerService发送消息"+new Date());  

  18. return message;  

  19.            }  

  20.        };  

  21.        jmsTemplate.send(this.destination,messageCreator);  

  22.    }  

  23. publicvoid convertAndSend(){  

  24.        MsgPoJo msgPojo = new MsgPoJo();  

  25.        msgPojo.setId("1");  

  26.        msgPojo.setText("first msg");  

  27.        System.out.println("--发送消息:msgPojo.id为"+msgPojo.getId()+";msgPojo.text为"+msgPojo.getText());  

  28.        jmsTemplate.convertAndSend(this.destination, msgPojo);  

  29.    }  

  30. publicvoid setJmsTemplate(JmsTemplate jmsTemplate) {  

  31. this.jmsTemplate = jmsTemplate;  

  32.    }  

  33. publicvoid setDestination(Destination destination) {  

  34. this.destination = destination;  

  35.    }  

  36. }  


同样在QueueConsumerService.java中增加receiveAndConvert()方法并在其实现类中实现,实现类的代码如下:


  1. package jms.mq.spring;  

  2. import javax.jms.Destination;  

  3. import javax.jms.JMSException;  

  4. import javax.jms.TextMessage;  

  5. import org.springframework.jms.core.JmsTemplate;  

  6. publicclass QueueConsumerService{  

  7.    JmsTemplate jmsTemplate;  

  8.    Destination destination;  

  9. publicvoid receive() {  

  10.        TextMessage message = (TextMessage) jmsTemplate.receive();  

  11. try {  

  12.            System.out.println("QueueConsumerService收到消息:"+message.getText());  

  13.        } catch (JMSException e) {  

  14.            e.printStackTrace();  

  15.        }  

  16.    }  

  17. publicvoid receiveAndConvert() {  

  18.        MsgPoJo msgPojo = (MsgPoJo)jmsTemplate.receiveAndConvert();  

  19. if(msgPojo!=null){  

  20.            System.out.println("--收到消息:msgPojo.id为"+msgPojo.getId()+";msgPojo.text为"+msgPojo.getText());  

  21.        }  

  22.    }  

  23. publicvoid setJmsTemplate(JmsTemplate jmsTemplate) {  

  24. this.jmsTemplate = jmsTemplate;  

  25.    }  

  26. publicvoid setDestination(Destination destination) {  

  27. this.destination = destination;  

  28.    }  

  29. }  



修改我们的两个测试类,增加对转换方法的调用,不再赘述,直接上代码:

QueueConsumerTest.java测试类

  1. package jms.mq.spring;  

  2. import org.springframework.context.ApplicationContext;  

  3. import org.springframework.context.support.ClassPathXmlApplicationContext;  

  4. publicclass QueueConsumerTest {  

  5. privatestatic ApplicationContext appContext = new ClassPathXmlApplicationContext( "applicationContext.xml");  

  6. privatestaticvoid receive() {  

  7.        QueueConsumerService consumerService = (QueueConsumerService) appContext.getBean("queueConsumerService");  

  8.        consumerService.receive();  

  9.    }  

  10. privatestaticvoid receiveAndConvert() {  

  11.        QueueConsumerService consumerService = (QueueConsumerService) appContext.getBean("queueConsumerService");  

  12.        consumerService.receiveAndConvert();  

  13.    }  

  14. publicstaticvoid main(String[] args) {  

  15. //receive();

  16.        receiveAndConvert();  

  17.    }  

  18. }  

QueueProducerTest.java测试类

  1. package jms.mq.spring;  

  2. import org.springframework.context.ApplicationContext;  

  3. import org.springframework.context.support.ClassPathXmlApplicationContext;  

  4. publicclass QueueProducerTest {  

  5. privatestatic ApplicationContext appContext = new ClassPathXmlApplicationContext( "applicationContext.xml");  

  6. privatestaticvoid send() {  

  7.        QueueProducerService producerService = (QueueProducerService) appContext.getBean("queueProducerService");  

  8.        producerService.send();  

  9.    }  

  10. privatestaticvoid convertAndSend() {  

  11.        QueueProducerService producerService = (QueueProducerService) appContext.getBean("queueProducerService");  

  12.        producerService.convertAndSend();  

  13.    }  

  14. publicstaticvoid main(String[] args) {  

  15. //send();

  16.        convertAndSend();  

  17.    }  

  18. }  


代码编写完毕,我们看一下我们的劳动成果。首先运行生产者类和消费者控制台信息如下:

SouthEast

SouthEast


收到的内容与发的内容相同,说明转换成功了。如果这一部分的程序使用的队列跟上面的一样,那你会发现发送的时候打印出的信息不值上面的一个,还包括一个接收的信息,这是为什么呢?了解spring原理的人应该知道,spring是把所有类都加载到内容中,当然也包括我们上门写的按个实现MessageListener的一个消费者类,他们也在运行,如果监听的地址跟你送的地址正好相同的话,他也有可能收到这个信息。所以在测试的时候要注意修改配置文件。


  1. <beanid="queueProducerService"class="jms.mq.spring.QueueProducerService">

  2. <propertyname="jmsTemplate"ref="jmsQueueTemplate"/>

  3. <propertyname="destination"ref="queueDest"/>

  4. </bean>

  5. <beanid="queueConsumerService"class="jms.mq.spring.QueueConsumerService">

  6. <propertyname="jmsTemplate"ref="jmsQueueTemplate"/>

  7. <propertyname="destination"ref="queueDest"/>

  8. </bean>


4、监听器上的使用方式

我再来学习一下跟监听器联合使用的方式,只在发布订阅者模式上演示一下。我们先来修改发布者的实现方式,在发布者中增加convertAndSend方法并在其实现类中实现,订阅者监听器没有类转换,不用修改,发布者修改后的代码如下:


  1. package jms.mq.spring;  

  2. import java.util.Date;  

  3. import javax.jms.Destination;  

  4. import javax.jms.JMSException;  

  5. import javax.jms.MapMessage;  

  6. import javax.jms.Message;  

  7. import javax.jms.Session;  

  8. import javax.jms.TextMessage;  

  9. import org.springframework.jms.core.JmsTemplate;  

  10. import org.springframework.jms.core.MessageCreator;  

  11. import jms.spring.QueueProducerService;  

  12. publicclass TopicPublisherService{  

  13.    JmsTemplate jmsTemplate;  

  14.    Destination destination;  

  15. publicvoid send() {  

  16.        MessageCreator messageCreator = new MessageCreator() {  

  17. public Message createMessage(Session session) throws JMSException {  

  18.                TextMessage message = session.createTextMessage();  

  19.                message.setText("QueueProducerService发送消息"+new Date());  

  20. return message;  

  21.            }  

  22.        };  

  23.        jmsTemplate.send(this.destination,messageCreator);  

  24.    }  

  25. publicvoid convertAndSend(Object obj) {  

  26.        System.out.println("--发送PoJo对象...");  

  27.        jmsTemplate.convertAndSend(destination, obj);  

  28.    }  

  29. publicvoid setJmsTemplate(JmsTemplate jmsTemplate) {  

  30. this.jmsTemplate = jmsTemplate;  

  31.    }  

  32. publicvoid setDestination(Destination destination) {  

  33. this.destination = destination;  

  34.    }  

  35. }  


发布订阅者配置文件如下


  1. <!-- 配置TopicJms模板 -->

  2. <beanid="jmsTopicTemplate"class="org.springframework.jms.core.JmsTemplate">

  3. <propertyname="connectionFactory"ref="connectionFactory"/>

  4. <propertyname="defaultDestination"ref="topicDest"/>

  5. <!-- 配置是否为发布订阅者模式,默认为false -->

  6. <propertyname="pubSubDomain"value="true"/>

  7. <!--<property name="receiveTimeout" value="10000" /> -->

  8. <propertyname="messageConverter"ref="msgConverter"></property>

  9. </bean>

  1. <beanid="topicPublisherService"class="jms.mq.spring.TopicPublisherService">

  2. <propertyname="jmsTemplate"ref="jmsTopicTemplate"/>

  3. <!-- <property name="destination" ref="topicDest" /> -->

  4. <propertyname="destination"ref="topicSubscriberMessageListenerDest"/>

  5. </bean>

  6. <beanid="topicSubscriberService"class="jms.mq.spring.TopicSubscriberService">

  7. <propertyname="jmsTemplate"ref="jmsTopicTemplate"/>

  8. <propertyname="destination"ref="topicDest"/>

  9. </bean>


修改上面的发布测试类,修改增加对新增方法的调用,修改后的内容如下:

  1. package jms.mq.spring;  

  2. import org.springframework.context.ApplicationContext;  

  3. import org.springframework.context.support.ClassPathXmlApplicationContext;  

  4. publicclass TopicPublisherTest {  

  5. privatestatic ApplicationContext appContext = new ClassPathXmlApplicationContext( "applicationContext.xml");  

  6. privatestaticvoid send() {  

  7.        TopicPublisherService topicPublisherService = (TopicPublisherService) appContext.getBean("topicPublisherService");  

  8.        topicPublisherService.send();  

  9.    }  

  10. privatestaticvoid convertAndSend() {  

  11.        TopicPublisherService topicPublisherService = (TopicPublisherService) appContext.getBean("topicPublisherService");  

  12.        MsgPoJo msgPoJo = new MsgPoJo();  

  13.        msgPoJo.setId("1");  

  14.        msgPoJo.setText("测试内容");  

  15.        topicPublisherService.convertAndSend(msgPoJo);  

  16.    }  

  17. publicstaticvoid main(String[] args) {  

  18. //send();

  19.        convertAndSend();  

  20.    }  

  21. }  

运行发布测试类,运行结果如下:

SouthEast

写在到这里,ActiveMQ与spring整合就讲完了,主要讲了ActiveMQ与spring的简单整合,监听器和类转换这些主要功能.















本文转自yunlielai51CTO博客,原文链接:http://blog.51cto.com/4925054/1288918,如需转载请自行联系原作者
相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
1月前
|
算法 NoSQL Java
2023年阿里高频Java面试题:分布式+中间件+高并发+算法+数据库
又到了一年一度的金九银十,互联网行业竞争是一年比一年严峻,作为工程师的我们唯有不停地学习,不断的提升自己才能保证自己的核心竞争力从而拿到更好的薪水,进入心仪的企业(阿里、字节、美团、腾讯.....)
|
1月前
|
算法 NoSQL Java
2021年阿里高频Java面试题:分布式+中间件+高并发+算法+数据库
又到了一年一度的金九银十,互联网行业竞争是一年比一年严峻,作为工程师的我们唯有不停地学习,不断的提升自己才能保证自己的核心竞争力从而拿到更好的薪水,进入心仪的企业(阿里、字节、美团、腾讯.....)
|
1月前
|
XML 中间件 数据格式
Django 高级指南:深入理解和使用类视图和中间件
Django 是一款强大的 Python Web 框架,它提供了一套完整的解决方案,让我们能够用 Python 语言快速开发和部署复杂的 Web 应用。在本文中,我们将会深入研究 Django 中的两个高级特性:类视图(Class-Based Views)和中间件(Middleware)。
|
2月前
|
开发框架 安全 Java
|
4月前
|
缓存 NoSQL 容灾
《Java应用提速(速度与激情)》——六、阿里中间件提速
《Java应用提速(速度与激情)》——六、阿里中间件提速
|
4月前
|
消息中间件 NoSQL Dubbo
阿里Java高级岗中间件二面:GC+IO+JVM+多线程+Redis+数据库+源码
一转眼,都2023年了,你是否在满意的公司?拿着理想的薪水? 虽然“钱多、事少、离家近”的工作可能离技术人比较远,但是找到一份合适的工作,其实并不像想象中那么难。但是,有些技术人确实是认真努力工作,但在面试时表现出的能力水平却不足以通过面试,或拿到高薪,其实不外乎以下 2 个原因: 第一,“知其然不知其所以然”。做了多年技术,开发了很多业务应用,但似乎并未思考过种种技术选择背后的逻辑。所以,他无法向面试官展现出自己未来技术能力的成长潜力。面试官也不会放心把具有一定深度的任务交给他。 第二,知识碎片化,不成系统。在面试中,面试者似乎无法完整、清晰地描述自己所开发的系统,或者使用的相关技术。
|
4月前
|
Java 中间件
|
4月前
|
SQL 算法 NoSQL
2023年阿里高频Java面试题:分布式+中间件+高并发+算法+数据库
又到了一年一度的金九银十,互联网行业竞争是一年比一年严峻,作为工程师的我们唯有不停地学习,不断的提升自己才能保证自己的核心竞争力从而拿到更好的薪水,进入心仪的企业(阿里、字节、美团、腾讯.....)
|
7月前
|
开发框架 前端开发 Java
java程序设计与j2ee中间件技术/软件开发技术(III)-大作业-采用MVC模式实现商品信息的查询显示(可以模糊查询)、增加和删除功能,商品表自拟,实现简单菜单操作和分页显示(三)
java程序设计与j2ee中间件技术/软件开发技术(III)-大作业-采用MVC模式实现商品信息的查询显示(可以模糊查询)、增加和删除功能,商品表自拟,实现简单菜单操作和分页显示
133 0
|
7月前
|
开发框架 前端开发 Java
java程序设计与j2ee中间件技术/软件开发技术(III)-大作业-采用MVC模式实现商品信息的查询显示(可以模糊查询)、增加和删除功能,商品表自拟,实现简单菜单操作和分页显示(二)
java程序设计与j2ee中间件技术/软件开发技术(III)-大作业-采用MVC模式实现商品信息的查询显示(可以模糊查询)、增加和删除功能,商品表自拟,实现简单菜单操作和分页显示
115 0
相关产品
云消息队列 MQ
微服务引擎
云消息队列 Kafka 版
推荐文章
更多