JMS即Java消息服務(Java Message Service)應用程序接口,是一個Java平台中關於面向消息中間件(MOM)的API,用於在兩個應用程序之間,或分布式系統中發送消息,進行異步通信。Java消息服務是一個與具體平台無關的API,絕大多數MOM提供商都對JMS提供支持。我們可以簡單的理解:兩個應用程序之間需要進行通信,我們使用一個JMS服務,進行中間的轉發,通過JMS 的使用,我們可以解除兩個程序之間的耦合。
JMS is asynchronous by default. So to receive a message, the client is not required to send the request. The message will arrive automatically to the client as they become available.(JMS 原本就是一個異步的消息服務,客戶端獲取消息的時候,不需要主動發送請求,消息會自動發送給可用的客戶端)
JMS provides the facility of assurance that the message will delivered once and only once. You know that duplicate messages create problems. JMS helps you avoiding such problems.(JMS保證消息只會遞送一次。大家都遇到過重復創建消息問題,而JMS能幫你避免該問題。)
JMS具有兩種通信模式:
1、Point-to-Point Messaging Domain (點對點)
2、Publish/Subscribe Messaging Domain (發布/訂閱模式)
在JMS API出現之前,大部分產品使用“點對點”和“發布/訂閱”中的任一方式來進行消息通訊。JMS定義了這兩種消息發送模型的規范,它們相互獨立。任何JMS的提供者可以實現其中的一種或兩種模型,這是它們自己的選擇。JMS規范提供了通用接口保證我們基於JMS API編寫的程序適用於任何一種模型。
a、模式圖:
b、涉及到的概念:
在點對點通信模式中,應用程序由消息隊列,發送方,接收方組成。每個消息都被發送到一個特定的隊列,接收者從隊列中獲取消息。隊列保留著消息,直到他們被消費或超時。
c、特點:
a、模式圖:
b、涉及到的概念:
在發布/訂閱消息模型中,發布者發布一個消息,該消息通過topic傳遞給所有的客戶端。該模式下,發布者與訂閱者都是匿名的,即發布者與訂閱者都不知道對方是誰。並且可以動態的發布與訂閱Topic。Topic主要用於保存和傳遞消息,且會一直保存消息直到消息被傳遞給客戶端。
c、特點:
在JMS中,消息的產生和消息是異步的。對於消費來說,JMS的消息者可以通過兩種方式來消費消息。
(1)、同步(Synchronous)
在同步消費信息模式模式中,訂閱者/接收方通過調用 receive()方法來接收消息。在receive()方法中,線程會阻塞直到消息到達或者到指定時間後消息仍未到達。
(2)、異步(Asynchronous)
使用異步方式接收消息的話,消息訂閱者需注冊一個消息監聽者,類似於事件監聽器,只要消息到達,JMS服務提供者會通過調用監聽器的onMessage()遞送消息。
(1)、Connection Factories
創建Connection對象的工廠,針對兩種不同的jms消息模型,分別有QueueConnectionFactory和TopicConnectionFactory兩種。可以通過JNDI來查找ConnectionFactory對象。客戶端使用一個連接工廠對象連接到JMS服務提供者,它創建了JMS服務提供者和客戶端之間的連接。JMS客戶端(如發送者或接受者)會在JNDI名字空間中搜索並獲取該連接。使用該連接,客戶端能夠與目的地通訊,往隊列或話題發送/接收消息。
QueueConnectionFactory queueConnFactory = (QueueConnectionFactory) initialCtx.lookup ("primaryQCF"); Queue purchaseQueue = (Queue) initialCtx.lookup ("Purchase_Queue"); Queue returnQueue = (Queue) initialCtx.lookup ("Return_Queue");
(2)、Destination
目的地指明消息被發送的目的地以及客戶端接收消息的來源。JMS使用兩種目的地,隊列和話題。如下代碼指定了一個隊列和話題:
創建一個隊列Session:
QueueSession ses = con.createQueueSession (false, Session.AUTO_ACKNOWLEDGE); //get the Queue object Queue t = (Queue) ctx.lookup ("myQueue"); //create QueueReceiver QueueReceiver receiver = ses.createReceiver(t);
創建一個Topic Session:
QueueSession ses = con.createQueueSession (false, Session.AUTO_ACKNOWLEDGE); //get the Queue object Queue t = (Queue) ctx.lookup ("myQueue"); //create QueueReceiver QueueReceiver receiver = ses.createReceiver(t);
(3)、Connection
Connection表示在客戶端和JMS系統之間建立的鏈接(對TCP/IP socket的包裝)。Connection可以產生一個或多個Session。跟ConnectionFactory一樣,Connection也有兩種類型:QueueConnection和TopicConnection。
連接對象封裝了與JMS提供者之間的虛擬連接,如果我們有一個ConnectionFactory對象,可以使用它來創建一個連接。
Connection connection = connectionFactory.createConnection();
(4)、Session
Session 是我們對消息進行操作的接口,可以通過session創建生產者、消費者、消息等。Session 提供了事務的功能,如果需要使用session發送/接收多個消息時,可以將這些發送/接收動作放到一個事務中。
我們可以在連接創建完成之後創建session:
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
這裡面提供了參數兩個參數,第一個參數是是否支持事務,第二個是事務的類型
(5)、Producter
消息生產者由Session創建,用於往目的地發送消息。生產者實現MessageProducer接口,我們可以為目的地、隊列或話題創建生產者;
MessageProducer producer = session.createProducer(dest); MessageProducer producer = session.createProducer(queue); MessageProducer producer = session.createProducer(topic);
(6)、Consumer
消息消費者由Session創建,用於接收被發送到Destination的消息。
MessageConsumer consumer = session.createConsumer(dest); MessageConsumer consumer = session.createConsumer(queue); MessageConsumer consumer = session.createConsumer(topic);
(7)、MessageListener
消息監聽器。如果注冊了消息監聽器,一旦消息到達,將自動調用監聽器的onMessage方法。EJB中的MDB(Message-Driven Bean)就是一種MessageListener。