標籤:
訊息驅動bean的主要用於接受和處理非同步訊息,這些資訊可能來自一個外部的系統或者同一個應用中的其它組件,之所以稱它們為非同步,那時因為這些訊息可以在任何時候到達,而不同於一般的遠程方法調用的結果,是立馬直接得到的。同UI的事件處理工作方式類似,訊息驅動bean用於監聽發送給它的非同步訊息。值得注意的是,與遠程調用方法不同,非同步訊息的寄件者不會停下來去等待對方的響應。
訊息驅動bean是J2EE中的一個標準服務(工具),全稱是Java Message Service API,簡稱為JMS。Java Message Service API是一個Java API,位於javax.jms包中,它為所有需要訊息系統服務的應用提供了一個介面。訊息系統能夠非同步發送和接受訊息,這些訊息可以是文本、對象或者其它的一些類型。這與遠端程序呼叫(RPC)模型是相反的,在遠端程序呼叫中,組件之間的互動都是同步發生的。任何一個符合JMS API規範的訊息系統的實現都可以稱做是一個JMS提供者(JMS Provider)。在J2EE SDK中內建有這個的一個JMS Provider,書中的例子也是使用的這個JMS Provider,各個供應商也有自己的商業實現用於在企業級應用中使用消費服務。書中給出的JMS例子的上下文可以用來表示:
在中,TimeIt是一個會話bean,它的主要作用就是向MessageWriter這個訊息驅動bean發送非同步訊息,TimeIt和MessageWriter這兩個企業bean可以稱之為JMS Clients,因為它們都是底層訊息系統的用戶端。訊息系統通過提供一個目的地(destination)存放訊息直至這些訊息被發送至接收方(recipient)來實現非同步通訊。中間的LogWriterQueue就是一個這樣的目的地,它儲存了所有來自TimeIt會話bean的訊息,這些訊息都將發往MessageWriter訊息驅動bean。在JMS中有兩種類型的目的地(destination):
● 隊列(Queue),用於儲存從一個JMS用戶端發往另一個JMS用戶端的訊息,這種訊息模型被稱為點對點(point-to-point);
● 主題(Topic),用於儲存從許多潛在的JMS用戶端發往多個潛在的JMS用戶端的訊息,這種訊息模型被稱為發布/訂閱(publish/subscribe)模式;
書中的例子所使用是的Queue類型的目的地。在中還有兩個“角色”:JMS訊息製造者和JMS訊息消費者,它們是JMS提供者裡面代表JMS用戶端去發送和接收訊息的類。當我們使用訊息驅動bean時,不必自己去建立一個JMS訊息消費者,因為EJB容器會替我們做這些事情,但是JMS訊息製造者就需要我們自己去建立了,我們需要建立一個JMS訊息製造者向目的地(可能是Queue也可能是Topic,書中例子是Queue,即中的LogWriterQueue)發送訊息。為了實現這個功能,我們需要兩個管理對象(administered object),它們通常是由JMS提供者所帶的管理工具所管理的,這兩個管理對象分別是:
● 串連工廠(connection factory),用於建立一個到JMS提供者的串連
● 目的地(destination),可以是javax.jsm.Queue和javax.jsm.Topic類型
一個典型的發送訊息的過程如下所示:
//第一步,得到串連工廠,書中例子因為使用的Queue類型目的地,所示這裡使用的
QueueConnectionFactory,其中XXXXX是部署時所設定的jndi名
InitialContext jndiContext = new InitialContext();
QueueConnectionFactory queueConnectionFactory =
(QueueConnectionFactory) jndiContext.lookup(“XXXX”)
//第二步,得到目的地,書中例子使用的Queue,XXXXX也是部署時設定的JNDI名
Queue queue = (Queue) jndiContext.lookup("XXXXX");
//第三步,從串連工廠中獲得一個串連
queueConnection =queueConnectionFactory.createQueueConnection();
//第四步,建立一個會話
QueueSession queueSession =
queueConnection.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
//第五步,為當前會話建立一個發往Queue的寄件者
QueueSender queueSender = queueSession.createSender(queue);
//第六步,建立一個訊息
TextMessage message = queueSession.createTextMessage();
SimpleDateFormat sdf =new SimpleDateFormat("yyyy.MM.dd ‘at‘ HH:mm:ss.SSS");
message.setText("log entry, the time is: " + sdf.format(new Date()));
//第七步,發送訊息
queueSender.send(message);
//第八步,關閉串連
queueConnection.close();
在訊息驅動bean中處理收到非同步訊息後所執行的動作,一個訊息驅動bean必須繼承兩個介面,它們是:
● MessageDirvenBean:包含了訊息驅動bean的生命週期方法
● MessageListener:包含onMessage()方法,當有一條訊息到達訊息驅動bean時這個方法會被調用。
(j2ee)訊息驅動bean