異步消息也可以由消息驅動豆來實現。在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.3in>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:mysourcecodeestjms>java -Djms.properties=%J2EE_HOME%configjms_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%libj2ee.jar;. java -Djms.properties=%J2EE_HOME%configjms_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.3in>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. |