三.消息驅動豆簡介 異步消息也可以由消息驅動豆來實現。在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.