ActiveMQ相關編程接口

 

JMS (Java Message Service)是由SUN開發的一套API,它爲開發者提供一套訪問MOM(Message-Oriented Middleware:面向消息中間件)的標準方法。
分爲兩種消息域PTP(點對點)和Pub/Sub(發佈/訂閱)。PTP消息被產生者放入到一個隊列中,消費者則從小消息列隊中取走消息,消息一擔取走,消息就從隊列中移除。Pub/Sub消息和PTP最大的不同在於發佈者發佈一條消息後可以發送給所有訂閱者,所有訂閱者都擁有處理某一條消息的機會。


JMS
 


JMS的一些重要接口
ConnectionFactory :創建一個受管理對象
Connection :連接到提供者的活動連接
Destination :一個封裝消息目標地址的受管理對象,如消息的來源地和發送滴,根據消息域的不同有兩個接口:Queue 和 Topic,前者對應PTP消息的目標地址,後者對應Pub/Sub消息的目標地址。
Session :發送和接受消息的單線程環境。(即一次會話)
MessageProducer:用於發送消息
MessageConsumer:用於接收消息
JMS高級接口與特定域接口(位於javax.jms包中)  
 

高級接口 PTP域子接口  PUB/SUB域子接口 
ConnectionFactory QueueConnectionFactory TopicConnectionFactory
Connection QueueConnection TopicConnection
Destination QueueDestination TopicDestination
Session QueueSession TopicSession
MessageProducer QueueMessageProducer TopicMessageProducer
MessageConsumer QueueMessageConsumer TopicMessageConsumer

 

一個典型的JMS程序要經過以下步驟才能開始創建和使用消息
1、通過JNDI查詢或創建ConnectionFactory
2、用ConnectionFactory創建一個Connection
3、用Connection創建一個或多個Session
4、通過JNDI查詢或創建一個或多個Destination
5、用Session和Destination創建對應的MessageProducer和MessageConsumer
6、啓動Connection
JMS消息結構
 
JMS根據不同應用的用途定義了多種消息類型,由Message接口派生而來,一個Message由Header、Properties和Body三個部分組成。
 
Header是一組標準鍵值字段,客戶端和提供者都用它來標識和路由消息。
Properties用於彌補Header的不足,可以通過手工設置其他的屬性,Message提供了set<Type>Property(String name)和get<Type>Property()方式來讓開發者任意定義屬性。
Body消息正文,包括了發送給其他程序的消息內容,根據消息體內容的不同,JMS擁有5個消息類型,並分別通過Message的5個子接口來描述。
 

消息類型 說明
TextMessage 消息是一個字符
ObjectMessage 消息是一個實現了Serializable接口的對象
MapMessage 消息是一個MAP,包括一組鍵值對元素,鍵位一個字符,值爲任意對象
BytesMessage 消息是一個二進制數組
StreamMessage 消息是一組JAVA原始類型數據,這些數據通過標準流操作按順序進行填充和讀取

 

 
消息收發的機制:
JMS事務使用了Session對它進行操作,分別擁有支持事務語義的3個方法,通過這些方法啓動,提交和回滾一個事務,這些方法分別是begin()、commit()和rollback()。
 
消息確認是接收者在成功接收到消息後,將一個回執發送給MOM,告之已經成功接收到一種通知機制。確認方式有三種分別是:
1、 Session.AUTO_ACKNOWLEDGE:在完成接收消息時,Session自動發送一個確認回執。
2、 Session.CLIENT_ACKNOWLEDGE:由客戶端程序通過手工調用Message.acknowledge()方法顯示確認接收。
3、 Session.DUPS_OK_ACKNOWLEDGE:讓Session延遲發送確認回執。
例如:創建一個不需事務,自動確認的session方式
         Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
 
爲什麼選用ActiveMQ
   1)ActiveMQ是一個開放源碼
   2)基於Apache 2.0 licenced 發佈並實現了JMS 1.1。
   3)ActiveMQ現在已經和作爲很多項目的異步消息通信核心了
   4)在很多中小型項目中採用ActiveMQ+SPRING+TOMCAT開發模式。

編程模式
消息產生者向JMS發送消息的步驟
(1)創建連接使用的工廠類JMS ConnectionFactory
(2)使用管理對象JMS ConnectionFactory建立連接Connection
(3)使用連接Connection 建立會話Session
(4)使用會話Session和管理對象Destination創建消息生產者MessageSender
(5)使用消息生產者MessageSender發送消息

消息消費者從JMS接受消息的步驟
(1)創建連接使用的工廠類JMS ConnectionFactory
(2)使用管理對象JMS ConnectionFactory建立連接Connection
(3)使用連接Connection 建立會話Session
(4)使用會話Session和管理對象Destination創建消息消費者MessageReceiver
(5)使用消息消費者MessageReceiver接受消息,需要用setMessageListener將MessageListener接口綁定到MessageReceiver
消息消費者必須實現了MessageListener接口,需要定義onMessage事件方法。
 
下載運行ActiveMQ
ActiveMQ5.0版本默認啓動時,啓動了內置的jetty服務器,提供一個demo應用和用於監控ActiveMQ的admin應用。運行%activemq_home%bin/目錄下的 activemq.bat 。
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616"); 
Destination destination = session.createQueue("QUEUE_NAME");
 

 

發送消息例子:
 
 


import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
import javax.jms.Destination;
 
publicclass MessageSender {
   
    /**
     *發送方法
     *@parammsgText
     */
    publicvoid send(String msgText){
      
       // 獲取jms連接
       Connection connection = null;
      
       try {
           // 獲取JNDI上下文
           InitialContext ctx = new InitialContext();
           ConnectionFactory cFactory = (ConnectionFactory)ctx.lookup("jndi/jmsConn");
          
           // 獲取Destination 目標地址
           Destination dest = (Destination)ctx.lookup("jndi/dest");
           ctx.close();
          
           // 獲取一個MOM的連接
           connection = cFactory.createConnection();
          
           // 創建JMS會話
           Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
          
           // 創建一個指定特定目標地址的消息發送者
           MessageProducer sender = session.createProducer(dest);
          
           // 建立Body內容
           TextMessage message = session.createTextMessage(msgText);
          
           // 發送給服務器
           sender.send(message);
          
       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           try {
              connection.close();
           } catch (Exception e) {
              e.printStackTrace();
           }
       }
    }
}
 

 

 
接收消息例子:
 
 


import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
 
publicclass MessageReceiver {
   
    /**
     *接收方法
     */
    publicvoid receive(){
       Connection connection = null;
      
       try {
           // 創建JNDI上下文
           InitialContext ctx = new InitialContext();
           ConnectionFactory cFactory = (ConnectionFactory)ctx.lookup("jndi/jmsConn");
          
           // 獲取目標地址信息
           Destination dest = (Destination)ctx.lookup("jndi/dest");
           ctx.close();
          
           // 獲取連接
           connection = cFactory.createConnection();
          
           // 獲取連接對話
           Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
          
           // 創建一個指向特定目標地址的消息消費者
           MessageConsumer receiver = session.createConsumer(dest);
          
           // 接收發送請求中的消息信息
           TextMessage textMsg = (TextMessage)receiver.receive();
          
           System.out.println("獲取內容:" + textMsg.getText());        
       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           try {
              connection.close();
           } catch (JMSException e) {
              e.printStackTrace();
           }
       }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章