前言
上篇博客《JMS實戰——ActiveMQ》介紹了ActiveMQ的安裝,並實現了簡單的PTP模型。這篇博客我們來看一下Pub-Sub模型,之後來總結一下JMS。
實現
項目結構
其中,一個消息發佈者Producer,兩個接收者Consumer1、Consumer2,還有兩個監聽類Listener1和2,負責監聽消費者是否收到消息。
消息生產者Producer
Producer類的代碼實現跟上篇博客中的Sender類十分類似,但要注意的是,destination = session.createTopic(“TestTopic2”); 我們創建的是topic而不再是queue。
//消息個數
private static final int SEND_NUMBER = 10;
public static void main(String[] args) {
//初始化開始,包括連接工廠、連接、會話、消息目的、消息生產者
ConnectionFactory connectionFactory;
Connection connection = null;
Session session;
Destination destination;
MessageProducer producer;
//創建連接工廠,使用默認用戶名和密碼。這裏tcp://localhost:61616爲連接地址,當然也可以使用默認地址。
connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
try {
// 構造從工廠得到連接對象
connection = connectionFactory.createConnection();
// 啓動
connection.start();
// 獲取操作連接
session = connection.createSession(Boolean.TRUE,
Session.AUTO_ACKNOWLEDGE);
//創建一個名稱爲TestQueue的消息隊列
destination = session.createTopic("TestTopic2");
//得到producer
producer = session.createProducer(destination);
// 構造消息
sendMessage(session, producer);
session.commit();
} catch (JMSException e) {
e.printStackTrace();
} finally {
try {
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
private static void sendMessage(Session session, MessageProducer producer) throws JMSException {
for (int i = 0; i < SEND_NUMBER; i++) {
TextMessage message=session.createTextMessage("I am a Producer"+i);
System.out.println("發送消息:"+message.getText());
producer.send(message);
}
}
消息的消費者Consumer
這裏就不再給出全部代碼了,但依然創建的是Topic,設置了消息監聽Listener1。
// 使用同一個消息隊列
destination = session.createTopic("TestTopic2");
consumer=session.createConsumer(destination);
consumer.setMessageListener(new Listener1());
監聽者Listener
public class Listener1 implements MessageListener{
@Override
public void onMessage(Message message) {
try {
System.out.println("訂閱者一收到消息:"+((TextMessage)message).getText());
} catch (Exception e) {
e.printStackTrace();
}
}
}
此處的MessageListener是jms包下提供的一個接口
package javax.jms;
/**
* @version $Rev: 467553 $ $Date: 2006-10-25 06:01:51 +0200 (Wed, 25 Oct 2006) $
*/
public interface MessageListener {
void onMessage(Message message);
}
測試
1 訂閱
發佈訂閱模型要先執行訂閱操作,依次執行Consumer1、Consumer2,之後在瀏覽器中查看Topic。
紅框中顯示已經存在2個Consumer。
2 發佈
執行Producer,這裏我們在代碼中給出的10個消息。因爲有2個訂閱者,所以入隊10個,出隊20。
此時,我們的監聽類Listener也發出了消息。查看控制檯輸出:
小結
ActiveMQ是基於JMS規範和J2EE規範的JMSProducer,也可以直接理解成是消息中間件。
1、與RMI、RPC相比,他的耦合性較小,更靈活。發佈消息者往往不需要了解誰會收到消息,這與遠程調用有着明顯的不同。
2、再有,一般的調用是同步的、耗時的。而JMS是異步的,大大改善了用戶體驗。