<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    【永恒的瞬間】
    ?Give me hapy ?
     

    Message-driven Bean

    Message-driven Bean是EJB2.0 規范中提出的的Enterprise Bean

    Message-driven Bean 的產生原因

    效率原因

    在JavaEE™平臺中,客戶端對Session Bean 和Entity Bean 的方法調用通過RMI或RMI-IIOP協議進行,這是傳統的通過網絡進行遠程調用的方法,當調用請求通過網絡傳播到容器,容器則將客戶端請求變成一序列的方法調用依次進行。客戶端只有在容器處理完請求并返回結果后方可繼續進行。

    可靠性的原因

    當客戶端對Session Bean或Entity Bean進行調用時,必須保證服務器容器處于運行狀態,如容器或網絡出現錯誤,客戶端調用將無法進行。

    事件的廣播

    傳統的RMI 或RMI-IIOP機制中,客戶端在某一時刻只能與某一具體的服務器通訊, 沒有任何內置的機制來將事件廣播到多個服務器。

    Message-driven Bean作為遠程方法調用的一種替代方法,在客戶端和服務器的直接方法調用之間放置了一個中間層,接收一個或多個客戶端的消息,并將消息轉發給一個或多個消息的使用者(Message Consumer)。

    通過消息機制而非直接的方法調用,客戶端可以繼續執行而不必等待服務器的運行結果,服務器可以選擇在方法調用完成后通知客戶,而消息機制本身保證了信息傳輸的可靠性,同時使用消息域(Message Domain)中的消息類型模型以達到事件廣播的機制。

    但是,對Message-Driven Bean 的使用也有一定的限制,如不適用于依賴于方法調用、要求具有明確的返回值才能繼續的客戶端程序。另外,如果在一個應用中過多的使用了Message-Driven Bean, 對應用的執行效率將會產生影響,所以不適用于對時間因素敏感的客戶端程序(如在下午兩點定購下午四點的機票,而在四點后才得到訂購是否成功的結果,這時結果已毫無用處)。

    Message-driven Bean 作為一般的JMS 使用者(consumer)

    作為一種具有JMS使用者(consumer)功能的Enterprise Bean組件模型,Message-Driven Bean由EJB容器進行管理,具有一般的JMS使用者(consumer)所不具有的優點,如對于一個Message-driven Bean,容器可創建多個實例來處理大量的并發消息,而一般的JMS使用者 (consumer)開發時則必須對此進行處理才能獲得類似的功能。同時Message-Driven Bean可取得EJB所能獲得的標準服務,如容器管理事務等服務。

    由于與Message-driven Bean相關的主題(Topic)或隊列(Queue)可以在部署時配置,因此,Message-driven Bean具有更多的靈活性。

    但注意,一個Message-driven Bean在部署時只可與一個具體的主題(Topic)或隊列(Queue) 建立關聯。如有多個主題(Topic)或隊列(Queue)需要與一個Message-driven Bean關聯,則 可以在部署時部署多個Message-driven Bean類,或使用一般的JMS使用者(consumer) 。

    Message-driven Bean 與其他Enterprise Bean

    作為Enterprise Bean組件模型之一,Message-driven Bean,具有一些與Session Bean 和Entity Bean相同的方法,但由于Message-driven Bean本身不處理客戶端調用,也無會話狀態,客戶只能通過向與Message Driven Bean關聯的隊列或主題發送消息從而與Message-driven Bean 進行交互,因此,Message-driven Bean 與Session Bean 和Entity Bean之間最大的不同之處在于Message-Driven Bean不具有組件接口及Home接口。

    另外,Message-driven Bean異步地處理隊列(Queue)或主題(Topic)中的消息,而非方法調用。

    Message-driven Bean

    Message-driven BeanJMS消息驅動的JavaEE™平臺服務器端組件,具備無狀態、支持事務的特點。當從JMS隊列(Queue)或主題(Topic)中接收到JMS消息后,由容器對組件進行調用。一般,可理解為消息的監聽器(Listener)及接收者(Consumer)。

    Message-driven Bean組件對于客戶端是不可見的。客戶端如希望調用封裝在組件中的業務邏輯,只能通過向組件監聽的JMS隊列(Queue)或主題(Topic)發送消息,然后容器以事件的形式向組件實例發送消息,組件實例根據消息的內容調用相應的業務邏輯或其他組件。

    因此,任何向組件監聽的特定JMS隊列(Queue)或主題(Topic)發送JMS消息的客戶端,即可視為Message-driven Bean的客戶端。

    Message-driven Bean組件模型不具備會話狀態,也就是說,當組件實例在沒有對客戶端的JMS消息提供處理的時候,所有的實例間沒有差別。

    Message-driven Bean的運行和客戶端的運行是異步的。同時,對于客戶端不可見。其實例由容器創建,其生存周期由容器控制。

    Message-driven BeanEJB容器、客戶端、消息系統

    下圖是EJB容器、客戶端、消息系統與EJB之間的關系:

    EJB容器、客戶端、消息系統與EJB之間的關系

    客戶端發送消息到JMS消息系統中的隊列或主題。Message-driven Bean在部署到容器中時,指定的隊列或主題,容器對其進行監聽;當容器從隊列或主題中接收到消息之后,將消息作為事件的一部分通知容器中相應的Message-driven Bean實例。

    組件模型單元

    Message-driven Bean由容器控制其生存周期,容器提供安全、并發、事務等等服務,對于客戶端來說,Message-driven Bean是不可見的。因此,Message-driven Bean不同于Session BeanEntity Bean,不具有組件接口和Home接口。

    Message-driven Bean組件模型包含兩個單元,即組件類和部署描述。下面分別對開發這些單元時,涉及的普遍過程、規則及注意事項進行描述。

    組件類

     javax.ejb.MessageDrivenBean接口

    EJB2.1規范中的Message-driven Bean組件中的組件類必須實現MessageDrivenBean接口。EJB3.0規范不強制Message-driven Bean實現該接口,而通過@MessageDriven注解進行標記并通過依賴注入與注解實現類似功能。

    MessageDrivenBean接口中定義了兩個容器管理回調的方法:

    ·             setMessageDrivenContext方法,容器創建Bean實例后,容器將調用該方法將由容器維護的Bean實例的上下文(context)與Bean實例進行關聯。EJB3.0規范中,可使用@Resource注解通知容器注入MessageDrivenContext實例。

    ·             ejbRemove方法,在實例被容器清除時,容器將調用此方法。一般,實例會在此方法中對實例占用的資源進行釋放。在EJB3.0規范中,可使用@PreDestroy注解標記此方法。

     javax.jms.MessageListener接口

    Message-driven Bean組件中的組件類必須實現MessageListener接口。

    在消息到達Message-driven Bean指定的監聽隊列或主題時,容器將調用javax.jms.MessageListener接口中定義的onMessage方法。開發者在此方法中提供對消息進行處理的業務邏輯。

    Session BeanEntity Bean不可實現javax.jms.MessageListener接口。

     javax.ejb.MessageDrivenContext接口

    容器將提供一個MessageDrivenContext對象,使實例可以訪問由容器維護的實例的上下文環境。在此接口中,定義了如下方法:

    ·             getEJBHomegetEJBLocalHome方法,從EJBContext接口繼承的方法,Message-driven Bean實例不可調用此方法;

    ·             getCallerPrincipal方法,從EJBContext接口繼承的方法,Message-driven Bean實例不可調用此方法;

    ·             isCallerInRole方法,從EJBContext接口繼承的方法,Message-driven Bean實例不可調用此方法;

    ·             setRollbackOnly方法,當前事務將被永久標記為回滾,不會被提交。只有容器管理事務的Message-driven Bean可被允許使用此方法;

    ·             getRollbackOnly方法,檢查當前事務是否已被標記為回滾。例如,EJB實例可以通過此方法,決定是否繼續在當前事務邊界內繼續進行計算。只有容器管理事務的Message-driven Bean可被允許使用此方法;

    ·             getUserTransaction方法,返回javax.transaction.UserTransaction接口。EJB實例可通過此接口對事務邊界進行劃分,并取得事務的狀態。只有容器管理事務的Message-driven Bean可被允許使用此方法;

     串行化的調用

    Apusic應用服務器中的EJB容器支持Message-driven Bean的多個實例的并發運行,但是每個實例只看到一個串行的方法調用過程,因此開發Message-driven Bean時,不需要將其以可重入(reentrant)的方式進行編寫。

     消息處理的并發

    Apusic應用服務器允許Message-driven Bean的多個實例并發執行,提供對流(Stream)消息并發處理。

     Message-driven Bean方法的事務上下文

    onMessage方法在何種事務范圍內被調用,取決于部署描述中指定的事物屬性,如Bean被指定使用容器管理的事務的方式,則必須將事務屬性設置為“Required”“NotSupported”

    Bean采用Bean管理的事務的方式,即使用javax.transaction.UserTransaction接口進行事務劃分時,導致Bean實例被調用的消息接收操作并非是事務中的一部分。如果希望消息接收操作是事務中的一部分,則Bean必須使用容器管理事務的方式,并且設置事務屬性為“Required”

     消息接收確認(Message Acknowledgement

    Message-driven Bean不能使用JMS API中提供的消息接收確認操作。消息接收確認操作由容器自動完成。如Bean采用了容器管理事務的方式,則消息接收確認操作作為事務提交的一部分自動進行。如使用了Bean管理事務的方式,消息接收確認操作不能作為事務提交的一部分,開發者可通過在部署描述中的acknowledge-mode元素指定消息接收確認操作的方式為AUTO_ACKNOWLEDGEDUPS_OK_ACKNOWLEDGE,如未指定acknowledge-mode元素,容器將使用AUTO_ACKNOWLEDGE方式進行消息接收確認操作。

    指定隊列(Queue)或主題(Topic

    Message-driven Bean被部署到容器時,必須關聯到某個消息隊列(Queue)或主題(Topic),以便容器對此隊列或主題進行監聽。

    開發者可通過@MessageDriven注解的mappedName屬性或部署描述文件中的message-driven-destination元素指定關聯的隊列或主題。

    Bean關聯的是一個消息主題,則通過部署描述中的subscription-durability元素指定對隊列進行的是持久還是非持久訂閱,如此元素未指定,則使用非持久訂閱的方式。

     異常處理

    Message-driven Bean中的onMessage方法不能聲明拋出java.rmi.RemoteException異常。

    一般來說,Message-driven Bean在運行期間不應向容器拋出RuntimeException異常。RuntimeException異常是指會導致Message-driven Bean進入不存在狀態的非應用級異常。如果Bean使用了Bean-managed事務并拋出了RuntimeException異常,容器不應確認收到了這條消息。

    從發信端看來,收信端一直存在,若發信端繼續對該目的地發送消息,容器會自動把消息轉向到其他Message-driven Bean實例。

    遺漏的PreDestroy調用

    在系統發生異常的情況下,不能保證容器總會調用BeanPreDestroy方法,因此,如果BeanPostConstruct方法中打開了一些資源,并在PreDestroy方法中釋放這些資源,在這種情況下,則這些資源不能被釋放。

    鑒于以上原因,使用Message-driven Bean的應用需要提供一種機制,以便周期性的清除這些未釋放的資源占用。

     必須遵守的規則

    在開發Message-driven Bean時,開發者必須遵守如下規則:

     組件類

    ·             使用EJB2.1規范時,必須間接或直接實現javax.ejb.MessageDrivenBean接口;使用EJB3.0規范時,可改為使用@MessageDriven注解對組件類進行標記。

    ·             必須間接或直接實現javax.jms.MessageListener接口;

    ·             類必須聲明為public,不可被聲明為finalabstract類;

    ·             必須擁有一個無參數的public構造函數(constructor);

    ·             類不能定義finalize()方法;

    ·             在原EJB2.1規范中,類必須實現ejbCreate()方法用來創建組件實例,在EJB3.0中,這一要求已被移除了。EJB3.0的兼容規則規定,如果Message-driven Bean類實現了ejbCreate()方法,將看作被@PostConstruct注解標記的方法處理。此時若同時使用@PostConstruct注解,則只能標記ejbCreate()方法。

     onMessage方法

    ·             方法必須被聲明為public

    ·             方法不能被聲明為finalstatic

    ·             返回值必須為void

    ·             方法只能有一個javax.jms.Message類型的參數;

    ·             不能拋出java.rmi.RemoteException異常

    ·             運行期間一般來說不應拋出RuntimeException。請參考:

     ejbRemove方法

    ·             方法名必須是ejbRemove;

    ·             方法必須被聲明為public

    ·             方法不能被聲明為finalstatic

    ·             返回值必須為void

    ·             方法不能有參數;

    ·             不能拋出java.rmi.RemoteException異常。

    ·             EJB3.0規范中,可使用@PreDestroy注解實現同樣效果。若實現javax.ejb.MessageDrivenBean接口同時使用注解,則只能把ejbRemove()方法注解為@PreDestroy

    生存周期

    下圖表示Message-driven Bean的生存周期。

    Message-driven Bean的生存周期

    posted on 2007-10-22 12:27 ???MengChuChen 閱讀(2706) 評論(0)  編輯  收藏 所屬分類: EJB3.0

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲人和日本人jizz| 亚洲第一福利视频| 亚洲码和欧洲码一码二码三码| 一区二区三区四区免费视频| 中文字幕中韩乱码亚洲大片| 日本高清免费观看| 亚洲精品~无码抽插| 成人一区二区免费视频| 国产亚洲色婷婷久久99精品91| 九九热久久免费视频| 亚洲人成亚洲人成在线观看| 在线观看免费视频一区| 日本亚洲欧洲免费天堂午夜看片女人员| 精品一区二区三区免费观看| 亚洲精品国产精品乱码视色| 日韩精品无码免费专区午夜| 亚洲AV电影院在线观看| 8x成人永久免费视频| 中文字幕亚洲精品无码| 免费在线观看的黄色网址| 国产又黄又爽又大的免费视频| 亚洲VA成无码人在线观看天堂 | 另类图片亚洲校园小说区| 免费大片在线观看网站| jizz18免费视频| 亚洲AV日韩精品久久久久久久 | 久草免费在线观看视频| 亚洲午夜福利在线视频| 亚洲av高清在线观看一区二区 | 一级特黄aa毛片免费观看| 亚洲午夜精品一区二区公牛电影院 | 亚洲成人免费在线观看| 亚洲一区二区三区高清在线观看| 四虎影视在线永久免费看黄| 99在线视频免费观看| 亚洲卡一卡2卡三卡4麻豆| 免费中文字幕一级毛片| 69精品免费视频| 国产成人va亚洲电影| 亚洲国产精品国自产拍电影| 国产成人高清精品免费软件|