1. 程式人生 > >(四) 訊息中介軟體——使用 JmsTemplate 向 ActiveMQ 傳送 Queue 型別訊息

(四) 訊息中介軟體——使用 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].https://blog.csdn.net/winter_chen001/article/details/78409125
[3].https://blog.csdn.net/u013123635/article/details/78362360
[4].https://www.cnblogs.com/Peter2014/p/8080192.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].https://blog.csdn.net/hpttlook/article/details/23391967
[9].https://blog.csdn.net/super_scan/article/details/39837591