訊息服務是分散式應用之間進行訊息傳遞的中介軟體,具備可靠、非同步、鬆散耦合、語言中立與平台中立等特性。其核心原理在於封裝傳送者與接收者之間的訊息,並在分散式訊息客戶端連接點增加一個軟體處理層,提供統一介面隔離底層複雜性。
Java 訊息服務(JMS)定義了 Java API 標準,規範客戶端如何與底層訊息供應商互動。JMS 支援兩種訊息模型:
EJB 2.0 引入訊息驅動 Bean (MDB),以 EJB 形式實現 JMS 訊息的非同步接收者。MDB 不對外暴露業務介面,僅實現 javax.ejb.MessageDrivenBean 與 javax.jms.MessageListener 介面,擁有單一 Bean 類別,類似無狀態 Session Bean:無會話狀態、實例等價、支援佇列池化與併發處理、可處理多客戶端訊息。
setMessageDrivenContext():容器注入 MessageDrivenContext,提供執行期上下文存取(如 JTA UserTransaction)。ejbCreate():無參數公共建構式,實例建立時調用,用於資源初始化(JMS 連線、資料庫連線等)。ejbRemove():容器決定調用時機,用於資源釋放。注意:拋出系統例外時不保證被調用,開發者需自行檢查清理。onMessage(Message msg):核心業務邏輯入口。容器將接收到的 JMS 訊息傳入,開發者需將其轉型為五種訊息類型之一(TextMessage、BytesMessage、ObjectMessage、MapMessage、StreamMessage)並處理。若在事務中,所有操作屬於同一事務;回滾將導致訊息重送。JMS 訊息包含標準 Header(getJMSXXX()/setJMSXXX())、屬性(getXXXProperty()/setXXXProperty())與 Body。五種 Body 類型分別對應不同資料格式。clearBody() 可清除 Body 並設為唯讀模式。
MDB 客戶端即普通 JMS 生產者,無需知曉消費者為 EJB。核心流程:JNDI 查找 ConnectionFactory → 建立 Connection → 建立 Session → 建立 Sender/Publisher → 發送訊息。
擴展自核心 JMS 架構,引入 QueueConnectionFactory、QueueConnection、QueueSession、QueueSender、Queue 等介面。createQueueSession() 參數控制事務支援與確認模式(AUTO_ACKNOWLEDGE、CLIENT_ACKNOWLEDGE、DUPS_OK_ACKNOWLEDGE)。訊息發送時可指定遞送模式、優先級、存活時間。
對應介面為 TopicConnectionFactory、TopicConnection、TopicSession、TopicPublisher、Topic。主題名稱層級結構由供應商實現。發布參數同佇列模式。
// JNDI 查找
queueConnectionFactory = (QueueConnectionFactory) jndiContext.lookup("java:comp/env/jms/MyQueueConnectionFactory");
queue = (Queue) jndiContext.lookup("java:comp/env/jms/QueueName");
// 建立連線與發送器
queueConnection = queueConnectionFactory.createQueueConnection();
queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queueSender = queueSession.createSender(queue);
// 發送多條訊息
message = queueSession.createTextMessage();
for (int i = 0; i < NUM_MSGS; i++) {
message.setText("我是" + msgArray[i]);
queueSender.send(message);
}
實作需滿足:public 類別、非 abstract/final、實作兩個介面、提供無參建構子、實作 onMessage()、ejbCreate()、ejbRemove()、不實作 finalize()。onMessage() 中轉型處理 TextMessage,異常時呼叫 mdc.setRollbackOnly() 標記事務回滾。
ejb-jar.xml 中 <message-driven> 定義 Bean 名稱、類別、目的地類型(javax.jms.Queue)、安全身分、容器管理事務(Required)。
j2ee -verbosej2eeadmin -addJmsDestination jms/MyQueue queuerunclient -client SimpleMessageApp.ear -name SimpleMessageClient -textauth輸出驗證:客戶端顯示發送訊息,伺服器控制台顯示 MDB 接收訊息。