(四) 消息中间件——使用 JmsTemplate 向 ActiveMQ 发送 Queue 类型消息

前言

在之前的几篇文章(https://blog.csdn.net/column/details/23061.html) 中我们介绍了 ActiveMQ 的安装启动,管理平台的查看,也介绍了 ActiveMQConnectionFactory、PooledConnectionFactory、ActiveMQQueue 、ActiveMQTopic和 JmsTemplate ,本文将继续深入一步,介绍使用 JmsTemplate 向 ActiveMQ 发送 Queue 类型的消息,并且在管理平台查看相应的变化。需要说明的是,本文将介绍两种发送消息的方式,并且展示 Java 对象 类型消息的发送。

发送类的编写

为了增加文章的易读性,本文直接将代码写在了一个类里,而没有采取 接口-接口实现 的形式,同时为了简化描述,省去了Spring Bean 扫描的配置,但是本文所涉及的方法体需要被注册为一个 Spring Bean,你应该认识注解 @Component(value=“jmsTemplateQueueProduct”) 的含义。

创建 类 JmsTemplateQueueProduct

这里需要注意的是 JmsTemplate 使用 @Resource 注入指定了 name ,在下面发送 Java 对象类型的数据时将会声明另一个 JmsTemplate,这样做是为了在消息接收时按照不通类型的数据处理。
声明 SimpleDateFormat 将用于记录方法被触发的具体时间。

/** * 使用 JmsTemplate 向Active 中发送 队列 消息 * @author jie.wu */
@Component(value="jmsTemplateQueueProduct")
public class JmsTemplateQueueProduct {
	//用于发送 String (字符串)类型的消息
	@Resource(name="JmsTemplateQueue")
	private JmsTemplate jmsTemplate;
	
	private SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
//···
}
方法一 send

send 方法需要我们重写 send 方法,好处是可以在内部多一些自定义的逻辑内容,坏处就是代码量有点多。
代码里输出信息有助于我们了解到程序运行的时间节点。

//方式一:JmsTemplate.send
	public void jmsTemplateQueueProductString(final String message){
		//输出信息,便于了解程序触发时间
		System.out.println(sdf.format(new Date())+":"+this.getClass().getName()+";jmsTemplateQueueProductString 收到消息:"+message+";转发给 ActiveMQ");
		jmsTemplate.send(new MessageCreator(){
			@Override
			public Message createMessage(Session session) throws JMSException {
				return session.createObjectMessage(message);
			}
		});
	}
方法二 convertAndSend

比较简单,看代码

//方式二:JmsTemplate.convertAndSend
	public void jmsTemplateQueueProductStringConvertAndSend(final String message){
		//输出信息,便于了解程序触发时间
		System.out.println(sdf.format(new Date())+":"+this.getClass().getName()+";jmsTemplateQueueProductStringConvertAndSend 收到消息:"+message+";转发给 ActiveMQ");
		jmsTemplate.convertAndSend(message);
	}
使用 convertAndSend 发送 Java 对象

Java 对象对应的实体类,必须实现序列化

public class User implements Serializable{  
	private static final long serialVersionUID = -1L;
	private Integer id;
    private String comment;
	// get、set 方法略
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "User[id="+id+",comment="+comment+"]";
	}  
}

新声明一个 JmsTemplate 和 ActiveMQQueue
这样做的原因是,本系列文章是 一个 JmsTemplate Bean 对应 一个 Queue Bean ,本质上是对不通 Queue 消息的发送,而消费者在获取消息时,如果不知道你的Queue 的消息类型,那将是一件十分麻烦的事情,所以我们新引入一个JmsTemplate,专门用于发送 Java 对象类型的消息,你需要从新声明一个 JmsTemplate 和 ActiveMQQueue ,请参照前文 https://blog.csdn.net/bestcxx/article/details/83036309
在 JmsTemplateQueueProduct 中做如下声明

//用于发送 Java 对象 类型的消息
	@Resource(name="JmsTemplateQueueForBean")
	private JmsTemplate JmsTemplateQueueForBean;

然后是发送 Bean 的代码

//JmsTemplate.convertAndSend 发送对象
	public void jmsTemplateQueueProductForBeanConvertAndSend(User user){
		//输出信息,便于了解程序触发时间
		System.out.println(sdf.format(new Date())+":"+this.getClass().getName()+";jmsTemplateQueueProductForBeanConvertAndSend 收到消息:"+user.toString()+";转发给 ActiveMQ");
		JmsTemplateQueueForBean.convertAndSend(user);
	}
测试代码
先看下 http://localhost:8161/admin/queues.jsp

起初是没有消息的

在这里插入图片描述

运行测试方法

你可以一个一个运行,上文展示了三个方法,两个String ,一个 Java 对象

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.bestcxx.stu.springmybatis.model.User;
@DirtiesContext  
@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(locations={"classpath:applicationContext.xml"})  
public class TestJmsTemplateQueueProduct {
	@Autowired
	private JmsTemplateQueueProduct jmsTemplateQueueProduct;
	@Test
	public void testJmsTemplateQueueProductString(){
		String message="124";
	jmsTemplateQueueProduct.jmsTemplateQueueProductString(message);
	}
	@Test
	public void testJmsTemplateQueueProductStringConvertAndSend(){
		String message="567";
	jmsTemplateQueueProduct.jmsTemplateQueueProductStringConvertAndSend(message);	
	}
	@Test
	public void testJmsTemplateQueueProductForBeanConvertAndSend(){
		User user=new User();
		user.setId(1);
		user.setComment("789");
jmsTemplateQueueProduct.jmsTemplateQueueProductForBeanConvertAndSend(user);
	}
	}	
}
运行结束后再看下 http://localhost:8161/admin/queues.jsp

在这里插入图片描述

其中 Name列的 queue_test 就是队列的名字 是在声明 ActiveMQQueue a=new ActiveMQQueue(“queue_test”); 时确定的
Number Of Pending Messages 表示收到的消息数量
Number Of Consumers 表示目前实时等待的消费者请求数量
Messages Enqueued 表示被存储的数量-Queue类型数据没有消费者消费将先被 ActiveMQ 存储起来
Messages Dequeued 表示被消耗的消息数

参考资料

[1].《Spring 实战 第4版》
[2].http://www.javashuo.com/article/p-nxexdxsc-cc.html
[3].http://www.javashuo.com/article/p-mhvwmafl-a.html
[4].http://www.javashuo.com/article/p-cfykdjws-dc.html
[5].https://blog.csdn.net/wowwilliam0/article/details/81110943
[6].https://blog.csdn.net/lsj960922/article/details/79926947
[7].https://blog.csdn.net/wangfengwf/article/details/78966704
[8].http://www.javashuo.com/article/p-rgvuricv-gv.html
[9].https://blog.csdn.net/super_scan/article/details/39837591