jms詳解2

來源:互聯網
上載者:User
  • JavaMessage ServiceJMS詳解
    本文向您介紹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不為特定的客戶保留資料或對話狀態。

 
  1. @MessageDriven(activationConfig={  
  2.    @ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Queue"),  
  3.    @ActivationConfigProperty(propertyName="destination",propertyValue="queue/jms")  
  4. }) 

@MessageDriven注釋指明這是一個訊息驅動Bean,並使用@ActivationConfigProperty注釋配置訊息的各種屬性,其 中destinationType屬性指定訊息的類型,訊息有兩種類型topics 和queues,下面是這兩種訊息類型的介紹:

Topics 可以有多個用戶端。用topic發布允許一對多,或多對多通訊通道。訊息的產生者被叫做publisher, JavaMessage Service接受者叫做subscriber。destinationType屬性對應值:javax.jms.Topic

Queue 僅僅允許一個訊息傳送給一個客戶。一個寄件者將訊息放入訊息佇列,接受者從隊列中抽取並得到訊息,訊息就會在隊列中消失。第一個接受者抽取並得到訊息後,其他人就不能再得到它。destinationType屬性對應值:javax.jms.Queue destination屬性用作指定訊息路徑,訊息驅動Bean在發布時,如果路徑不存在,容器會自動建立該路徑,當容器關閉時該路徑會自動被刪除

當一個訊息到達queue/jms隊列時,就會觸發onMessage方法,訊息作為一個參數傳入.

 
  1. package com.julycn.jms;  
  2.  
  3. import javax.ejb.ActivationConfigProperty;  
  4. import javax.ejb.MessageDriven;  
  5. import javax.jms.JMSException;  
  6. import javax.jms.Message;  
  7. import javax.jms.MessageListener;  
  8. import javax.jms.TextMessage;  
  9.  
  10. @MessageDriven(activationConfig = {  
  11.         @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),  
  12.         @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/jms") })  
  13. public class MessageQueue implements MessageListener {  
  14.  
  15.     public MessageQueue() {  
  16.  
  17.     }  
  18.  
  19.     public void onMessage(Message message) {  
  20.         TextMessage tmsg = (TextMessage) message;  
  21.         try {  
  22.             System.out.println(tmsg.getText());  
  23.         } catch (JMSException e) {  
  24.             e.printStackTrace();  
  25.         }  
  26.     }  
  27.  
 
  1. package com.julycn.client;  
  2.  
  3. import javax.jms.JMSException;  
  4. import javax.jms.Queue;  
  5. import javax.jms.QueueConnection;  
  6. import javax.jms.QueueConnectionFactory;  
  7. import javax.jms.QueueSender;  
  8. import javax.jms.QueueSession;  
  9. import javax.jms.TextMessage;  
  10. import javax.naming.InitialContext;  
  11. import javax.naming.NamingException;  
  12.  
  13. public class MessageQueueClient {  
  14.  
  15.     public static void main(String[] args) {  
  16.         QueueConnection conn;  
  17.         QueueSession session;  
  18.         Queue queue;  
  19.         QueueSender sender;  
  20.         TextMessage msg;  
  21.  
  22.         try {  
  23.             InitialContext ctx = new InitialContext();  
  24.             QueueConnectionFactory qcf = (QueueConnectionFactory) ctx  
  25.                     .lookup("ConnectionFactory");  
  26.             conn = qcf.createQueueConnection();  
  27.             session = conn.createQueueSession(false,  
  28.                     QueueSession.AUTO_ACKNOWLEDGE);  
  29.             queue = (Queue) ctx.lookup("queue/jms");  
  30.             msg = session.createTextMessage("你好,好久不見!");  
  31.             sender = session.createSender(queue);  
  32.             sender.send(msg);  
  33.             sender.close();  
  34.         } catch (NamingException e) {  
  35.             e.printStackTrace();  
  36.         } catch (JMSException e) {  
  37.             e.printStackTrace();  
  38.         }  
  39.  
  40.     }  
  41.  

(1) 得到一個JNDI初始化上下文(Context);

例子對應代碼:

Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.provider.url", "localhost: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.lookup("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 :客戶機通過調用訊息的acknowledge方法來接收訊息。接收發生在session層。接收到一個被消費的訊息時,將自動接收該session已經 消費的所有訊息。例如:如果訊息的消費者消費了10條訊息,然後接收15 個被傳遞的訊息,則前面的10 個訊息的收據都會在這15 個訊息中被接收。

Session.DUPS_ACKNOWLEDGE :指示session緩慢接收訊息。

(5) 尋找目的地(Topic/ Queue);

例子對應代碼:queue =(Queue) ctx.lookup("queue/jms");

(6) 根據會話以及目的地來建立訊息製造者(TopicPublisher/QueueSender)和消費者(TopicSubscriber/QueueReceiver).
例子對應代碼:

msg = session.createTextMessage("你好,好久不見!");
sender = session.createSender(queue);
sender.send(msg);

備忘:如果運行時出現javax.naming.NameNotFoundException: jms not bound , 是因為JBoss不會自已建立一個Queue對象,因此,需要手工來配置Queue對象。可以<JBoss5.x安裝目錄>/server/default/deploy目錄中建立一個xxx-service.xml檔案,其中xxx可以任意取值,但必須跟“-service”尾碼,例如,abc-service.xml。該檔案可以放在deploy或其子目錄(可以是多層子目錄)中。該檔案的內容如下:

 
  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <server> 
  3.     <mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=jms"> 
  4.         <depends optional-attribute-name="DestinationManager"> 
  5.             jboss.mq:service=DestinationManager</depends> 
  6.     </mbean> 
  7. </server> 

<mbean>元素的name屬性值中的name必須是jms,要與queue/jms中的/後面的部分一致.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.