JavaMessage ServiceJMS詳解時間:2009-11-24 21:33來源: 作者: 點擊:49次
本文向您介紹Java中的Message ServiceJMS,JavaMessage Service提供了點對點模式和發布-訂閱模式,文中將詳細介紹這兩種服務。
本文向您介紹Java中的Message ServiceJMS,JavaMessage Service協助了點對點模式和發布-訂閱模式,文中將詳細介紹這兩種服務。
JavaMessage Service(JMS Java Message Services)協助了點對點模式(Point-to-Point Queue)和發布-訂閱模式(Publish-Subscribe Topics).
Queue僅允許一個的訊息傳送給一個的客戶(一對一):
JavaMessage ServiceJMS的接收者和寄件者之間不存在時間上的依賴聯絡。不論寄件者發送訊息時接收者也許在運行,接收者都沒成績提取訊息。接收者對於勝利處理的訊息給出回執。
Topics沒成績有多個用戶端(一對多,多對多):
向某個話題訂閱的客戶程式只能收到那些在它訂閱之後發布的訊息。為了接收到訊息,訂閱者必需保持聚會狀態。因此,發行者和訂閱者之間存在時間上的依賴聯絡。
點對點訊息模式經過一個的訊息佇列(Queue)出現,訊息的生產者向隊列寫入訊息,訊息的訂閱者從隊列提取訊息。發布-訂閱訊息模式經過一個的話題(Topic)節點構成的層次架構出現,訊息的生產者向那個層次架構發布訊息,訊息的訂閱者向那個架構訂閱訊息。
訊息驅動的Bean只有一個的Bean類。從某些方面看,JMS訊息驅動的Bean類似於無狀態對話Bean:訊息驅動的Bean不為特定的客戶保留資料或對話狀態。
@MessageDriven(activationConfig={
@ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination",propertyValue="queue/jms")
})
@MessageDriven注釋指明這是一個的訊息驅動Bean,並應用@ActivationConfigProperty注釋配置訊息的各種屬性,其 中destinationType屬性指定訊息的類別,訊息有兩種類別topics 和queues,下面是這兩種訊息類別的介紹:
Topics 沒成績有多個用戶端。用topic發布允許一對多,或多對多通訊通道。訊息的產生者被叫做publisIT, JavaMessage Service接受者叫做subscriber。destinationType屬性對應value:javax.jms.Topic
Queue 僅僅允許一個的訊息傳送給一個的客戶。一個的寄件者將訊息放入訊息佇列,接受者從隊列中抽取並得到訊息,訊息就會在隊列中消失。第一個的接受者抽取並得到訊息後,更多相關人就不能再得到它。destinationType屬性對應value:javax.jms.Queue destination屬性用作指定訊息路徑,訊息驅動Bean在發布時,假如路徑不存在,容器會自動建立該路徑,當容器關閉時該路徑會自動被刪除
當一個的訊息到達queue/jms隊列時,就會觸發onMessage竅門,訊息作為一個的參數傳入.
package com.julycn.jms;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/jms") })
public class MessageQueue implements MessageListener {
public MessageQueue() {
}
public void onMessage(Message message) {
TextMessage tmsg = (TextMessage) message;
try {
System.out.println(tmsg.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
package com.julycn.client;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class MessageQueueClient {
public static void main(String[] args) {
QueueConnection conn;
QueueSession session;
Queue queue;
QueueSender sender;
TextMessage msg;
try {
InitialContext ctx = new InitialContext();
QueueConnectionFactory qcf = (QueueConnectionFactory) ctx
.seeup("ConnectionFactory");
conn = qcf.createQueueConnection();
session = conn.createQueueSession(false,
QueueSession.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.seeup("queue/jms");
msg = session.createTextMessage("你好,好久不見!");
sender = session.createSender(queue);
sender.send(msg);
sender.close();
} catch (NamingException e) {
e.printStackTrace();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
(1) 得到一個的JNDI初始化上下文(Context);
例子對應原始碼:
Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "org.jnp.inte編程ces.NamingContextFactory");
props.setProperty("java.naming.provider.url", "www.verybc.com:1099");
props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");
InitialContext ctx = new InitialContext(props);
留意:沒成績寫在原始碼中,也沒成績寫在jndi.properties文檔中.
(2) 根據上下文來尋找一個的串連工廠TopicConnectFactory/ QueueConnectionFactory (有兩種串連工廠,根據是topic/queue來應用相應的類別);
例子對應原始碼:
QueueConnectionFactory qcf =(QueueConnectionFactory) ctx.seeup("ConnectionFactory");
(3) 從串連工廠得到一個的串連(Connect 有兩種[TopicConnection/ QueueConnection]);
例子對應原始碼:conn = qcf.createQueueConnection();
(4) 經過串連來建立一個的對話(Session);
例子對應原始碼:session= conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
這句原始碼意思是:建立不需求事務的並且能自動接收JavaMessage Service收條的對話,在非事務Session 中,JMS訊息傳遞的方法有三種:
Session.AUTO_ACKNOWLEDGE :當客戶機調用的receive竅門勝利返回,或當MessageListenser 勝利處理了訊息,session將會自動接收訊息的收條。
Session.CLIENT_ACKNOWLEDGE :客戶機經過調用訊息的acknowingledge竅門來接收訊息。接收除了在session層。接收到一個的被消費的訊息時,將自動接收該session已經 消費的所有訊息。例如:假如訊息的消費者消費了10條訊息,然後接收15 個被傳遞的訊息,則前面的10 個訊息的收據都會在這15 個訊息中被接收。
Session.DUPS_ACKNOWLEDGE :指示session緩慢接收訊息。
(5) 尋找目的地(Topic/ Queue);
例子對應原始碼:queue =(Queue) ctx.seeup("queue/jms");
(6) 根據對話以及目的地來建立訊息製造者(TopicPublisIT/QueueSender)和消費者(TopicSubscriber/QueueReceiver).
例子對應原始碼:
msg = session.createTextMessage("你好,好久不見!");
sender = session.createSender(queue);
sender.send(msg);
備忘:假如運行時出現javax.naming.NameNotFoundException: jms bound , 是由於JBoss不會自已建立一個的Queue對象,因此,需求手工來配置Queue對象。沒成績/server/default/deploy列表中建立一個的編程-service.xml文檔,其中編程沒成績任意取value,但必需跟“-service”尾碼,例如,abc-service.xml。該文檔沒成績放在deploy或其子列表(沒成績是多層子列表)中。該文檔的內容如下:
jboss.mq:service=DestinationManager元素的title屬性value中的title必需是jms,要與queue/jms中的/後面的部份一致.
【非常編程推薦】