三.消息驅動豆簡介
異步消息也可以由消息驅動豆來實現。在EJB 1.1規范中,定義了兩種類型的EJB。分別是實體豆(Entity Bean)和會話豆(Session Bean)。客戶端通常是以同步的,阻塞方式來調用豆的方法。消息驅動豆將EJB和JMS的功能結合在一起。
正如前述,會話豆通常實現商務邏輯,客戶端不能共享一個會話豆。實體豆通常和一些在永久存儲中的一些實體條目相對應的。這兩種豆通常都有REMOTE和HOME接口,用來與客戶端交互。並且,這些交互都是同步的,阻塞方式進行的。比如,一個請求發送給一個豆,通過阻塞式方法調用,服務器返回一個相應。調用者在收到返回後,才能進行下一步處理。消息驅動豆通常配置成是一個特別的主題(topic)或隊列的客戶端,作為消息的使用者。但消息驅動豆沒有HOME和REMOTE接口。一個消息產生者將消息寫入TOPIC或隊列時,並不知道使用者是一個消息驅動豆。這就允許集成一個分布式的計算系統時,有很大的靈活性。消息驅動豆沒有會話性質的狀態,所有的實例在不處理請求時是相同的,這與無狀態會話豆是類似的。將豆的實例放在緩沖池裡,也是高效處理消息驅動豆的一種方法。一個消息驅動豆必須間接或直接地從javax.ejb.MessageDrivenBean接口繼承而來。這個接口是由javax.jms.MessageListener繼承而來。這個方法的一個參數是javax.jms.Message。可以是任何有效的JMS消息類型。方法的申明中並不包含一個thrown語句。因此在消息處理中,不會仍出應用程序異常。當容器接收到消息時,它首先是從一個緩沖池裡得到現成的一個消息驅動豆,然後,如果配置文件需要的,容器還要設置一個和事務處理上下文的一個聯系。當這些管理任務完成時,接收到的消息傳遞給onMessage()方法。一旦方法完成,事務確認或返回,豆又被重新放回到緩沖池。
ejbRemove()在把消息驅動豆從任何存儲上刪除時調用。並進行清楚操作和垃圾收集。必須在ejbRemove()方法中釋放所有豆的實例用到的資源。
setMessageDrivenConnection()方法只有一個參數-javax.ejb.MessageDrivenContext的實例。MessageDrivenContext類與在實體和會話豆中的上下文類似。當一個豆的實例創建時,容器傳入豆用的上下文。上下文中得到環境信息的方法,以及JTA UserTranscation類,用於豆管理事務處理的場合。
另外,豆提供者必須提供一個ejbCreate()方法(無參數),用於在EJB服務器對豆進行設置。豆實例可以在ejbCreate()方法中取得任何需要的資源。
消息驅動豆大大地簡化了創建一個JMS使用者,創建和配置一個JMS消息使用者這些功能都交由EJB容器來做了。開發人員只需簡單地實現消息驅動豆的接口,配置給EJB服務器,用來創建一個接收消息的商業邏輯部件。
四.一個實例
本文為了說明上面的概念,編寫了一個消息驅動豆,一個Publisher和一個Subscriber的代碼。
下面講一下怎樣運行實例。這裡假設讀者已經從SUN主頁上下載了J2EE SDK 1.3 Bate,並已經安裝好了。
1.創建一個WeatherReport
主題(Topic):
j2eeadmin -addJmsDestination WeatherReport topic
可以用下面命令看一下是否正確創建:
D:\j2sdkee1.3\bin>j2eeadmin -listJmsDestination JmsDestination
一般顯示結果如下:
< JMS Destination : jms/Topic , javax.jms.Topic >
< JMS Destination : jms/Queue , javax.jms.Queue >
< JMS Destination : WeatherReport , javax.jms.Topic >
2.運行Subscriber:
D:\mysourcecode\testjms>java -Djms.properties=%J2EE_HOME%\config\jms_client.properties jmssub
一般顯示結果如下:
Topic name is WeatherReport
Java(TM) Message Service 1.0.2 Reference Implementation (build b10)
To end program, enter Q or q, then
Reading message: A sunny day.
3.運行Publisher:
打開另一個命令行窗口,輸入下面命令:
set classpath=%J2EE_HOME%\lib\j2ee.jar;.
java -Djms.properties=%J2EE_HOME%\config\jms_client.properties jmspub
一般顯示結果如下:
Topic name is WeatherReport
Java(TM) Message Service 1.0.2 Reference Implementation (build b10)
Publishing message: A sunny day.
4.刪除一個話題
D:\j2sdkee1.3\bin>j2eeadmin -removeJmsDestination MyTopic
5.使用消息驅動豆
下面是用消息驅動豆實現接受消息。使用deploytool將附錄中的Bean部署好,可以看到下面的信息:
Deploying message driven bean MsgBean, consuming from WeatherReport
Application testjms deployed.
然後再次運行Publisher。可以看到消息驅動豆輸出下面的結果:
MESSAGE BEAN: Message received: A sunny day.