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

胡献根 2013-09-04

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

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

1、转换类的相关代码POJO

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

package jms.mq.spring;  
  
import java.io.Serializable;  
  
public class MsgPoJo implements Serializable{  
    private String id;  
    private String text;  
    public String getId() {  
        return id;  
    }  
    public void setId(String id) {  
        this.id = id;  
    }  
    public String getText() {  
        return text;  
    }  
    public void setText(String text) {  
        this.text = text;  
    }     
}  

2.转换类的实现

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

package jms.mq.spring;  
  
import javax.jms.JMSException;  
import javax.jms.Message;  
import javax.jms.Session;  
import javax.jms.TextMessage;  
  
import org.springframework.jms.support.converter.MessageConversionException;  
import org.springframework.jms.support.converter.MessageConverter;  
  
public class MsgConverter implements MessageConverter{  
  
    @Override  
    public Object fromMessage(Message message) throws JMSException,  
    MessageConversionException {  
        if (!(message instanceof TextMessage)) {  
            throw new MessageConversionException("Message is not TextMessage");  
        }  
        System.out.println("--转换接收的消息--");  
        TextMessage textMessage = (TextMessage) message;  
        MsgPoJo msgPojo = new MsgPoJo();  
        String[] texts=textMessage.getText().split(",");  
        msgPojo.setId(texts[0]);  
        msgPojo.setText(texts[1]);  
        return msgPojo;  
    }  
  
    @Override  
    public Message toMessage(Object object, Session session) throws JMSException,  
    MessageConversionException {  
        if (!(object instanceof MsgPoJo)) {  
            throw new MessageConversionException("obj is not MsgPojo");  
        }  
        System.out.println("--转换发送的消息--");  
        MsgPoJo msgPojo = (MsgPoJo) object;  
        TextMessage textMessage = session.createTextMessage();  
        textMessage.setText(msgPojo.getId()+","+msgPojo.getText());  
        return  textMessage;  
    }  
}  

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

package jms.mq.spring;  
  
import java.util.Date;  
  
import javax.jms.Destination;  
import javax.jms.JMSException;  
import javax.jms.Message;  
import javax.jms.Session;  
import javax.jms.TextMessage;  
import org.springframework.jms.core.JmsTemplate;  
import org.springframework.jms.core.MessageCreator;  
  
public class QueueProducerService{  
    JmsTemplate jmsTemplate;  
  
    Destination destination;  
  
    public void send() {  
        MessageCreator messageCreator = new MessageCreator() {  
            public Message createMessage(Session session) throws JMSException {  
                TextMessage message = session.createTextMessage();  
                message.setText("QueueProducerService发送消息"+new Date());  
                return message;  
            }  
  
        };  
        jmsTemplate.send(this.destination,messageCreator);  
    }  
      
    public void convertAndSend(){  
        MsgPoJo msgPojo = new MsgPoJo();  
        msgPojo.setId("1");  
        msgPojo.setText("first msg");  
        System.out.println("--发送消息:msgPojo.id为"+msgPojo.getId()+";msgPojo.text为"+msgPojo.getText());  
        jmsTemplate.convertAndSend(this.destination, msgPojo);  
    }  
  
  
    public void setJmsTemplate(JmsTemplate jmsTemplate) {  
        this.jmsTemplate = jmsTemplate;  
    }  
      
    public void setDestination(Destination destination) {  
        this.destination = destination;  
    }  
}  

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

package jms.mq.spring;  
  
import javax.jms.Destination;  
import javax.jms.JMSException;  
import javax.jms.TextMessage;  
import org.springframework.jms.core.JmsTemplate;  
  
  
public class QueueConsumerService{  
  
    JmsTemplate jmsTemplate;  
  
    Destination destination;  
  
    public void receive() {  
        TextMessage message = (TextMessage) jmsTemplate.receive();  
        try {  
            System.out.println("QueueConsumerService收到消息:"+message.getText());  
  
        } catch (JMSException e) {  
            e.printStackTrace();  
        }  
    }  
  
    public void receiveAndConvert() {  
        MsgPoJo msgPojo = (MsgPoJo)jmsTemplate.receiveAndConvert();  
        if(msgPojo!=null){  
            System.out.println("--收到消息:msgPojo.id为"+msgPojo.getId()+";msgPojo.text为"+msgPojo.getText());  
        }  
    }  
  
    public void setJmsTemplate(JmsTemplate jmsTemplate) {  
        this.jmsTemplate = jmsTemplate;  
    }  
  
    public void setDestination(Destination destination) {  
        this.destination = destination;  
    }  
}  

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

QueueConsumerTest.java测试类

package jms.mq.spring;  
  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
  
public class QueueConsumerTest {  
    private static ApplicationContext appContext = new ClassPathXmlApplicationContext( "applicationContext.xml");  
  
    private static void receive() {  
        QueueConsumerService consumerService = (QueueConsumerService) appContext.getBean("queueConsumerService");  
        consumerService.receive();  
    }  
  
    private static void receiveAndConvert() {  
        QueueConsumerService consumerService = (QueueConsumerService) appContext.getBean("queueConsumerService");  
        consumerService.receiveAndConvert();  
    }  
  
  
    public static void main(String[] args) {  
        //receive();  
        receiveAndConvert();  
    }  
}  

QueueProducerTest.java测试类

package jms.mq.spring;  
  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
  
public class QueueProducerTest {  
    private static ApplicationContext appContext = new ClassPathXmlApplicationContext( "applicationContext.xml");  
  
    private static void send() {  
        QueueProducerService producerService = (QueueProducerService) appContext.getBean("queueProducerService");  
        producerService.send();  
    }  
      
    private static void convertAndSend() {  
        QueueProducerService producerService = (QueueProducerService) appContext.getBean("queueProducerService");  
        producerService.convertAndSend();  
    }  
  
    public static void main(String[] args) {  
        //send();  
        convertAndSend();  
    }  
  
}  

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

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

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

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

package jms.mq.spring;  
  
import java.util.Date;  
  
import javax.jms.Destination;  
import javax.jms.JMSException;  
import javax.jms.MapMessage;  
import javax.jms.Message;  
import javax.jms.Session;  
import javax.jms.TextMessage;  
  
import org.springframework.jms.core.JmsTemplate;  
import org.springframework.jms.core.MessageCreator;  
  
import jms.spring.QueueProducerService;  
  
public class TopicPublisherService{  
    JmsTemplate jmsTemplate;  
       
    Destination destination;  
  
    public void send() {  
        MessageCreator messageCreator = new MessageCreator() {  
  
            public Message createMessage(Session session) throws JMSException {  
                TextMessage message = session.createTextMessage();  
                message.setText("QueueProducerService发送消息"+new Date());  
                return message;  
            }  
        };  
        jmsTemplate.send(this.destination,messageCreator);  
    }  
  
    public void convertAndSend(Object obj) {  
        System.out.println("--发送PoJo对象...");  
        jmsTemplate.convertAndSend(destination, obj);  
    }  
  
      
    public void setJmsTemplate(JmsTemplate jmsTemplate) {  
        this.jmsTemplate = jmsTemplate;  
    }  
  
    public void setDestination(Destination destination) {  
        this.destination = destination;  
    }  
  
}  

发布订阅者配置文件如下

package jms.mq.spring;  
  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
  
public class TopicPublisherTest {  
    private static ApplicationContext appContext = new ClassPathXmlApplicationContext( "applicationContext.xml");  
  
    private static void send() {  
        TopicPublisherService topicPublisherService = (TopicPublisherService) appContext.getBean("topicPublisherService");  
        topicPublisherService.send();  
    }  
    private static void convertAndSend() {  
        TopicPublisherService topicPublisherService = (TopicPublisherService) appContext.getBean("topicPublisherService");  
        MsgPoJo msgPoJo = new MsgPoJo();  
        msgPoJo.setId("1");  
        msgPoJo.setText("测试内容");  
        topicPublisherService.convertAndSend(msgPoJo);  
    }  
  
  
    public static void main(String[] args) {  
        //send();  
        convertAndSend();  
    }  
}  

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

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

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

呵呵,写到不好,请大家不要拍砖。

相关推荐

wuddny的blog / 0评论 2012-11-15