国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
ENTERPRISE JAVABEANS 3.0規(guī)范簡(jiǎn)介
    EJB ( Enterprise JavaBeans )技術(shù)是一種J2EE技術(shù),用于開發(fā)和部署基于組件的業(yè)務(wù)應(yīng)用程序。使用EJB架構(gòu)編寫的應(yīng)用程序是可伸縮的、事務(wù)性的,
并且是多用戶安全的。

 雖然EJB架構(gòu)具有豐富的功能,但其復(fù)雜性阻礙了它的廣泛應(yīng)用。在EJB領(lǐng)域,競(jìng)爭(zhēng)性技術(shù)紛至沓來。例如,O/R映射技術(shù)(如Toplink和開源的Hibernate
框架)已經(jīng)超越EJB,成為開發(fā)持久性解決方案的優(yōu)先選項(xiàng)。介紹EJB 3.0規(guī)范是吸引開發(fā)人員回到EJB的重大舉措。規(guī)范的目標(biāo)分為兩部分:

    使開發(fā)人員的EJB開發(fā)更為輕松。
    標(biāo)準(zhǔn)化持久性框架。

  EJB 3.0能讓我們更加接近將EJB按常規(guī)JavaBean對(duì)待的夢(mèng)想。它減少了開發(fā)人員要提供的編程工件數(shù),消除了需要實(shí)現(xiàn)的回調(diào)方法或?qū)⑵錅p至最少,并降低了實(shí)體bean編碼模型和O/R映射模型的復(fù)雜性。借助于EJB 3.0,J2EE可以得到更廣泛的應(yīng)用。

  在本文中,首先我們將簡(jiǎn)要討論一下EJB 2.1的局限性。接下來,通過逐個(gè)介紹提出的重大更改來描述EJB 3.0如何解決這些難題,更改包括EJB類型、O/R映射模型、實(shí)例關(guān)系模型和EJB QL(EJB查詢語(yǔ)言)等方面。最后,以基于EJB 3.0的EJB代碼示例來結(jié)束本文。

EJB 2.1的局限性

  使用EJB 2.1開發(fā)EJB不是一件容易的事。原因如下:

  • 要?jiǎng)?chuàng)建單個(gè)EJB,需要?jiǎng)?chuàng)建大量XML部署描述符。

  • 必須創(chuàng)建一個(gè)包含三個(gè)源文件的集合。

  • 必須實(shí)現(xiàn)多個(gè)回調(diào)方法,這些方法通常永遠(yuǎn)都用不到。

  • 必須拋出和獲取多個(gè)不必要的異常類型。

  • 由于容器管理實(shí)體bean之類的組件屬于抽象類,所以離開了容器的上下文,就完全不能對(duì)EJB進(jìn)行測(cè)試。

  • 最后,目前的EJB-QL形式在功能上有所限制,而且難于使用。這些限制迫使開發(fā)人員使用straight JDBC和SQL,或者使用其他持久性框架,如Toplink和Hibernate。

  冗長(zhǎng)的API是件讓人頭疼的事,EJB 3.0在這方面進(jìn)行了重要嘗試,解決了大多數(shù)問題。本文涵蓋了此規(guī)范的主要內(nèi)容。

部署描述符方法的終結(jié)

  XML部署描述符的配置是在簡(jiǎn)化EJB開發(fā)時(shí)的主要瓶頸。因此,EJB 3.0規(guī)范的主要目標(biāo)之一就是使開發(fā)人員免于處理XML文件。我們通過將添加到JDK 5.0中的元數(shù)據(jù)注釋用作JSR 175 JCP規(guī)范的一部分而實(shí)現(xiàn)了這一點(diǎn)。注釋是一種面向?qū)傩缘木幊?,類似于Xdoclet。但與需要預(yù)編譯的Xdoclet不同的是,注釋是通過Java編譯器在編譯時(shí)編譯到類中的。從開發(fā)人員的觀點(diǎn)出發(fā),注釋是與public/private類似的限定符,可以在類、字段或方法中使用:

import javax.ejb.*; @Stateless public class MyAccountBean implements MyAccount { @Tx(TxType.REQUIRED) @MethodPermission({"customer"}) public void deposit(double money) {...}

  注釋一般是自解釋的。@Stateless注釋指示bean無狀態(tài)。@Tx屬性指定方法的事務(wù)性聲明,@MethodPermission屬性指定被允許訪問方法的用戶。因此,這意味著不再需要編寫XML部署描述符來描述這些屬性。不過,這并沒有排除XML的使用;只不過使其成為可選方案。該規(guī)范允許使用XML部署描述符重寫這些注釋。

POJO編程模型

  需要注意的關(guān)鍵一點(diǎn)是,上述無狀態(tài)會(huì)話bean示例是自行結(jié)束的。拋開注釋,此文件就是一個(gè)JavaBean,也稱為簡(jiǎn)單傳統(tǒng)Java對(duì)象(Plain Old Java Object,POJO)。對(duì)于實(shí)體bean來說,接口是可選的,而對(duì)于會(huì)話bean和消息驅(qū)動(dòng)bean來說,接口則是必需的。然而,這并不意味著必須為會(huì)話bean或消息驅(qū)動(dòng)bean定義接口。如果不實(shí)現(xiàn)接口,則會(huì)自動(dòng)生成bean接口。根據(jù)在bean類中使用的注釋,生成的接口類型可能是本地的或遠(yuǎn)程的。bean的所有公共方法都將作為自動(dòng)生成的業(yè)務(wù)接口的一部分被包括在內(nèi):

public interface ShoppingCart { public void purchase(Product product, int quantity); public void emptyCart(); }

  如果希望選擇應(yīng)該向客戶端公開的接口的方法,或者為接口指定一個(gè)不同于自動(dòng)生成名稱的名稱,則建議顯式生成接口。

  此接口類是一個(gè)簡(jiǎn)單傳統(tǒng)Java接口(Plain Old Java Interface,POJI)。接口和bean類都不必拋出不必要的異常,如RemoteException。

回調(diào)方法

  在EJB 2.1規(guī)范中,開發(fā)人員必須實(shí)現(xiàn)bean類中的多種回調(diào)方法,如ejbActivate()、ejbPassivate()、ejbLoad()和ejbStore(),其中大多數(shù)方法永遠(yuǎn)不會(huì)使用。在3.0中,已經(jīng)沒有實(shí)現(xiàn)這些方法的強(qiáng)制規(guī)定了。在EJB 3.0中,bean開發(fā)人員不必實(shí)現(xiàn)不必要的回調(diào)方法,而可以將任意方法指定為回調(diào)方法來接收生命周期事件的通知。任何回調(diào)方法都必須使用預(yù)先定義的生命周期事件回調(diào)注釋進(jìn)行注釋。生命周期事件回調(diào)方法注釋的示例包括PostConstruct、PreDestroy、PostActivate或PrePassivate。有些事件回調(diào)方法對(duì)所有類型的EJB通用,而有些bean是特定于bean類型的(如用于實(shí)體bean的PostPersist)。

  回調(diào)方法可以在bean類中定義,也可以在bean監(jiān)聽器類中定義。Bean監(jiān)聽器類是使用與其關(guān)聯(lián)的bean類上的CallbackListener注釋表示的。在兩種情況下,對(duì)回調(diào)方法使用的注釋都是相同的,只有方法簽名不相同。在監(jiān)聽器類中定義的回調(diào)方法必須將對(duì)象用作參數(shù);而當(dāng)回調(diào)在bean自身中時(shí)則不需要。此對(duì)象參數(shù)可用于將bean實(shí)例傳遞到監(jiān)聽器類中的方法。下面是一個(gè)將回調(diào)方法置于實(shí)體bean中的示例:

@Entity public class AccountBean{ @PostPersist insertAccountDetails(AccountDetails accountDetails) public void createAccount(){} }

  現(xiàn)在來看一個(gè)創(chuàng)建監(jiān)聽器類并將其添加到bean類的示例。以下代碼定義回調(diào)監(jiān)聽器AccountListener:

/* Adds callback listener to bean class */ @CallbackListener AccountListener public class AccountBean{ public void createAccount(){} }

  以下代碼將回調(diào)監(jiān)聽器添加到Account Bean中:

/* Callback method defined inside a Listener class*/ public class AccountListener{ @PostPersist insertAccountDetails( AccountDetails accountDetails){} }

  由于@PostPersist用于注冊(cè)對(duì)剛剛被注入數(shù)據(jù)庫(kù)的對(duì)象調(diào)用的方法,在這種情況下,每次使用AccountBean中的createAccount()方法時(shí),都將調(diào)用insertAccountDetails()方法。

按異常進(jìn)行配置

  “按異常進(jìn)行配置”的方法是EJB 3.0中各個(gè)方面的指導(dǎo)方法,用于簡(jiǎn)化開發(fā)工作。它旨在通過使開發(fā)人員只在默認(rèn)值不適用的地方編碼,從而簡(jiǎn)化其工作。

  例如,在很多情況下,可以使用默認(rèn)值而不使用顯式元數(shù)據(jù)注釋元素。在這些情況下,開發(fā)人員無需指定元數(shù)據(jù)注釋即可獲得與完全指定注釋相同的結(jié)果。例如,默認(rèn)情況下,實(shí)體bean(由@Entity進(jìn)行注釋)具有一個(gè)默認(rèn)的實(shí)體類型CMP,指示它具有容器管理的持久性。這些默認(rèn)值可以簡(jiǎn)化對(duì)EJB的注釋。默認(rèn)值始終表示最常見的要求。例如,如果未指定注釋,則對(duì)EJB使用容器管理的事務(wù)劃分(其中的容器是相對(duì)于bean而言的,用于管理數(shù)據(jù)庫(kù)工作單元的提交或回滾)。類似地,為會(huì)話和消息驅(qū)動(dòng)bean生成默認(rèn)業(yè)務(wù)接口將公開接口中bean的所有公共方法,因?yàn)檫@是最常見的用例。

對(duì)象關(guān)系映射

  O/R映射或持久性模型已發(fā)生了重大變化,從基于抽象持久性模式的方法轉(zhuǎn)變?yōu)闀r(shí)下流行的各種與POJO相關(guān)的方法所促生出的一種方法。O/R映射使用注釋指定。O/R映射元數(shù)據(jù)表達(dá)應(yīng)用程序?qū)?yīng)用域的實(shí)體和關(guān)系映射到數(shù)據(jù)庫(kù)的需要和期望。

  在EJB 2.1中,開發(fā)人員使用他們自己的機(jī)制處理某些特定于數(shù)據(jù)庫(kù)的操作,如主鍵生成。而EJB 3.0提供了針對(duì)多個(gè)特定于數(shù)據(jù)庫(kù)的操作的支持。O/R映射模型具有對(duì)本機(jī)SQL的內(nèi)部支持。在本文中,我們雖然在討論實(shí)體bean中的更改時(shí)會(huì)簡(jiǎn)述持久性框架,但我們不提供其詳細(xì)信息。有關(guān)詳細(xì)信息,請(qǐng)查看EJB 3.0 API規(guī)范并下載EJB 3.0持久性文檔。

使用注釋封裝JNDI查找

  通過使用注釋、依賴注入機(jī)制和簡(jiǎn)單查找機(jī)制,EJB 3.0解決了環(huán)境依賴性和的JNDI訪問的封裝問題。

  EJB的上下文由其容器上下文及其資源和環(huán)境上下文組成。bean可以使用以下兩種方式訪問其資源引用及其上下文中的其他環(huán)境條目:

  • 讓容器向其提供使用注入之類的引用;例如,@EJB public AddressHome addressHome;自動(dòng)使用JNDI名稱AddressHome查找EJB。

  • 使用添加到j(luò)avax.ejb.EJBContext接口的Object lookup(String name)方法。此方法可用于查找綁定在bean的JNDI環(huán)境命名上下文中的資源及其他環(huán)境條目。

依賴注入

  Bean通過依賴性注釋來聲明資源或其環(huán)境上下文中其他條目上的依賴性。依賴性注釋指定bean所依賴的對(duì)象或資源的類型、特征以及用于接受訪問的名稱。

   以下是依賴性注釋的示例:

  @EJB(name="mySessionBean", beanInterface=MySessionIF.class)

   @Resource(name="myDB", type="javax.sql.DataSource.class")

  依賴性注釋可以被附加到bean類或其實(shí)例變量或方法。需要為依賴性注釋指定的信息量取決于它對(duì)上下文的使用以及可以從該上下文推斷出的信息量。

使用@Resource注入隨機(jī)資源

  @EJB注釋僅注入EJB存根。更加通用的依賴注入注釋為@Resource。使用@Resource注釋,可以使用對(duì)象的JNDI名稱從JNDI注入任何服務(wù)對(duì)象。全局(java:/)和本地(java:comp/env) JNDI樹都將被搜索到。以下示例注入消息連接工廠和消息隊(duì)列:

  @Resource (name="ConnectionFactory") QueueConnectionFactory factory;

  @Resource (name="queue/A") Queue queue;

  對(duì)于“知名”對(duì)象,如TimerService和SessionContext,JNDI名稱是標(biāo)準(zhǔn)名稱;因此@Resource注釋無需顯式指定name屬性即可注入這些對(duì)象:

  @Resource TimerService tms;

  @Resource SessionContext ctx;

  與@EJB annotation類似,@Resource注釋可應(yīng)用于setter方法,@Resources注釋可應(yīng)用于數(shù)組。@EJB和@Resource注釋都特定于它們注入的資源。它們可以簡(jiǎn)化開發(fā)人員的工作。

代碼示例

  在以下示例中,將為變量customerDB分配一個(gè)JNDI名稱為myDB的DataSource對(duì)象。需要指定name屬性,因?yàn)槲覀冞x擇的變量的名稱customerDB不同于JNDI名稱myDB。type屬性不需要指定,因?yàn)樗梢詮淖兞康念愋停ɡ?,DataSource)派生。

@Stateless public class MySessionBean implements MySession { //type is inferred from variable @Resource(name="myDB") public DataSource customerDB; public void myMethod1(String myString){ try  { Connection conn = customerDB.getConnection(); ... catch (Exception ex) } }

對(duì)EJB四種類型的更改

  我們知道,EJB有四種,EJB 3.0對(duì)每種EJB類型都進(jìn)行了更改。在本部分中,我們將查看對(duì)每種EJB類型提出的更改。EJB 3.0中的一個(gè)主要優(yōu)點(diǎn)是,所有托管的服務(wù)對(duì)象都是POJO(如會(huì)話bean)或非常輕量級(jí)的組件(如消息驅(qū)動(dòng)bean)。不難發(fā)現(xiàn),EJB 3.0已經(jīng)使EJB的開發(fā)變得更加容易和簡(jiǎn)單。

無狀態(tài)會(huì)話bean

  EJB 3.0會(huì)話bean是由EJB容器管理的POJO。

  會(huì)話bean的功能由其服務(wù)接口(又稱為業(yè)務(wù)接口,是一種簡(jiǎn)單傳統(tǒng)Java接口)定義。會(huì)話bean使用該接口類名稱從服務(wù)器的JNDI檢索該bean的存根對(duì)象。存根對(duì)象實(shí)現(xiàn)bean的服務(wù)接口。然后,客戶端可以針對(duì)存根對(duì)象調(diào)用bean接口方法。存根對(duì)象僅將調(diào)用傳遞給容器中的實(shí)際bean實(shí)例對(duì)象,該對(duì)象只有這些方法的實(shí)現(xiàn),并不進(jìn)行實(shí)際工作。存根對(duì)象由EJB容器自動(dòng)生成,它知道如何將bean方法調(diào)用轉(zhuǎn)到容器——開發(fā)人員無需提供存根對(duì)象的實(shí)現(xiàn)。在無狀態(tài)會(huì)話bean中,客戶端存根對(duì)象可以將方法調(diào)用轉(zhuǎn)到容器管理對(duì)象池中可用的任何bean實(shí)例。因此,不必在bean類中使用任何用于保存bean狀態(tài)的字段。

業(yè)務(wù)接口

  業(yè)務(wù)接口為無狀態(tài)會(huì)話bean所需。但這種接口并不總是需要定義。如果不定義,它們會(huì)自動(dòng)生成。根據(jù)在bean類中使用的注釋,生成的接口類型可能是本地的或遠(yuǎn)程的;如果沒有注釋,則為本地接口。bean的所有公共方法都將作為自動(dòng)生成的業(yè)務(wù)接口的一部分被包括在內(nèi)。

主接口

  無狀態(tài)會(huì)話bean不需要主接口??蛻舳丝梢酝ㄟ^變量的注入或注釋的方法獲取無狀態(tài)會(huì)話bean的引用。

bean類

  無狀態(tài)會(huì)話bean必須通過無狀態(tài)注釋進(jìn)行注釋,或者在部署描述符中表示為無狀態(tài)會(huì)話bean。bean類無需實(shí)現(xiàn)javax.ejb.SessionBean接口。@Stateless 注釋指示bean為無狀態(tài)會(huì)話bean:

@Stateless public class TraderBean implements Trader { public void buy (String symbol, int quantity){ System.out.println("Buying "+quantity+ " of "+ symbol); } public void sell (String symbol, int quantity);{ System.out.println("Selling "+quantity+ " of "+ symbol); } }

會(huì)話bean客戶端

  將會(huì)話bean部署到EJB 3.0容器中后,存根對(duì)象將被創(chuàng)建,并在服務(wù)器的JNDI注冊(cè)庫(kù)中進(jìn)行注冊(cè)??蛻舳舜a使用JNDI中接口的類名稱獲取bean的存根。下面的存根實(shí)例展示了如何為此JSP頁(yè)面檢索TraderBean??梢葬槍?duì)存根對(duì)象調(diào)用方法,該調(diào)用將被透明地委托給EJB 3.0容器中的bean實(shí)例:

private Trader tr = null; public void initialize () { try { InitialContext ctx = new InitialContext(); tr = (Trader) ctx.lookup( Trader.class.getName()); }catch (Exception e) { e.printStackTrace (); } } // ... ... public void service (Request req, Response rep) { // ... ... double res = tr.buy("SNPS",1000); }

無狀態(tài)會(huì)話bean的回調(diào)

  以下無狀態(tài)會(huì)話bean的生命周期事件回調(diào)是受支持的:

  • PostConstruct

  • PreDestroy

  在容器執(zhí)行任何依賴注入之后、調(diào)用bean上的第一個(gè)業(yè)務(wù)方法之前,將回調(diào)PostConstruct。PostConstruct方法在未指定的事務(wù)上下文和安全上下文中調(diào)用。

  在銷毀bean實(shí)例時(shí),將回調(diào)PreDestroy。PreDestroy方法在未指定的事務(wù)和安全上下文中執(zhí)行。

遠(yuǎn)程和本地接口

  會(huì)話bean還可以實(shí)現(xiàn)多個(gè)接口,每個(gè)接口針對(duì)一個(gè)不同類型的客戶端。默認(rèn)情況下,該接口用于與EJB 3.0容器運(yùn)行于同一JVM中的“本地”客戶端。通過Java引用進(jìn)行的方法調(diào)用既快又有效。另一類型的會(huì)話bean接口為遠(yuǎn)程接口,這種接口用于遠(yuǎn)程客戶端。當(dāng)客戶端通過遠(yuǎn)程接口查找會(huì)話bean存根時(shí),容器返回實(shí)現(xiàn)遠(yuǎn)程接口的序列化存根對(duì)象。即使是在集群環(huán)境中,遠(yuǎn)程存根也知道如何將遠(yuǎn)程過程調(diào)用(RPC)傳遞給服務(wù)器。遠(yuǎn)程接口也是簡(jiǎn)單傳統(tǒng)Java接口。

  注意,使用遠(yuǎn)程接口涉及對(duì)存根的序列化和反序列化,而且所有對(duì)bean實(shí)例的調(diào)用都需要通過網(wǎng)絡(luò)進(jìn)行。與使用本地接口相比,此方法相當(dāng)?shù)托?。因此,?yīng)該避免從本地客戶端查找遠(yuǎn)程接口。

  在會(huì)話bean實(shí)現(xiàn)中,應(yīng)該使用@Local and @Remote注釋為此bean指定本地和遠(yuǎn)程接口。下面是一個(gè)實(shí)現(xiàn)本地和遠(yuǎn)程接口的示例bean:

@Stateless @Local ({Trader.class}) @Remote ({RemoteTrader.class}) public class TraderBean implements Trader, RemoteTrader { public void buy (String symbol, int quantity){ System.out.println("Buying "+quantity+ " of "+ symbol); } public void sell (String symbol, int quantity);{ System.out.println("Selling "+quantity+ " of "+ symbol); } }

  @Local和@Remote注釋還可用于代替bean實(shí)現(xiàn)類來標(biāo)記會(huì)話bean接口。例如,以下代碼片斷指定RemoteTrader為遠(yuǎn)程接口。有了這一代碼片斷,就不再需要TraderBean上的@Remote標(biāo)記了。

有狀態(tài)會(huì)話bean

  有狀態(tài)會(huì)話bean是一種保持其內(nèi)部狀態(tài)的會(huì)話bean。如果客戶端針對(duì)同一個(gè)bean存根調(diào)用多個(gè)方法調(diào)用,則這些調(diào)用將始終連接到容器中的同一個(gè)bean實(shí)例。因此,只要客戶端應(yīng)用程序保留bean存根(或本地客戶端的引用),bean實(shí)例中的所有字段變量都將保留其值。

業(yè)務(wù)接口

  EJB 3.0 API上的有狀態(tài)會(huì)話bean的業(yè)務(wù)接口也是簡(jiǎn)單傳統(tǒng)Java接口。業(yè)務(wù)接口為有狀態(tài)會(huì)話bean所需。但這種接口并不總是需要定義。如果不定義,它們會(huì)自動(dòng)生成。根據(jù)在bean類中使用的注釋,生成的接口類型可能是本地的或遠(yuǎn)程的;如果不存在注釋,則其為本地接口。Bean的所有公共方法都將作為自動(dòng)生成的業(yè)務(wù)接口的一部分被包括在內(nèi)。

主接口

  有狀態(tài)會(huì)話bean不需要主接口。

bean類

  有狀態(tài)會(huì)話bean必須通過有狀態(tài)注釋進(jìn)行注釋,或者在部署描述符中表示為有狀態(tài)會(huì)話bean。bean類無需實(shí)現(xiàn)javax.ejb.Session Bean接口。有狀態(tài)會(huì)話bean可實(shí)現(xiàn)SessionSynchronization接口。

  有狀態(tài)TraderBean的實(shí)現(xiàn)非常簡(jiǎn)單。我們將實(shí)現(xiàn)類注釋為@Stateful,并使用Java對(duì)象(如Integer、String)備份在會(huì)話bean接口中定義的bean屬性。在客戶端會(huì)話開始時(shí),Java對(duì)象會(huì)在創(chuàng)建每個(gè)bean實(shí)例時(shí)對(duì)其進(jìn)行初始化。下面是TraderBean類的完整代碼。注意,有狀態(tài)會(huì)話bean類必須實(shí)現(xiàn)可序列化接口,以便容器可以序列化bean實(shí)例并保存它們,從而在不使用這些實(shí)例時(shí)保留其狀態(tài)信息。

@Stateful public class TraderBean implements Trader, Serializable { public String symbol = ""; public int quantity = 0; public void buy (String symbol, int quantity){ System.out.println("Buying "+quantity+ " of "+ symbol); } public void sell (String symbol, int quantity);{ System.out.println("Selling "+quantity+ " of "+ symbol); } public String getSymbol(){ return symbol; } public int getQuantity(){ return quantity; } // Other getter methods for the attributes ... }

會(huì)話bean客戶端

  下面是一個(gè)示例客戶端:

Trader tr = null; if (tr == null) { try { InitialContext ctx = new InitialContext(); tr = (Trader) ctx.lookup( Trader.class.getName()); } catch (Exception e) { e.printStackTrace (); } } // Make use of the tr object

有狀態(tài)會(huì)話bean的回調(diào)

  有狀態(tài)會(huì)話bean支持以下生命周期事件的回調(diào):構(gòu)造、銷毀、激活和鈍化。EJB 3.0規(guī)范定義了多個(gè)bean可用來在其生命周期中指定回調(diào)方法的注釋。容器在會(huì)話bean生命周期的不同階段自動(dòng)調(diào)用這些注釋方法??梢允褂靡韵伦⑨寴?biāo)記bean類中的任何方法:

  • @PostConstruct:容器會(huì)在實(shí)例化bean實(shí)例后立即調(diào)用該注釋方法。此注釋對(duì)于有狀態(tài)和無狀態(tài)會(huì)話bean都可用。

  • @PreDestroy:容器在從其對(duì)象池中銷毀不使用的或過期的bean實(shí)例前調(diào)用此注釋方法。此注釋對(duì)于有狀態(tài)和無狀態(tài)會(huì)話bean都可用。

  • @PrePassivate:如果某個(gè)有狀態(tài)會(huì)話bean實(shí)例閑置時(shí)間過長(zhǎng),則容器可能鈍化它,并將其保存在緩存中。此注釋標(biāo)記的方法在容器鈍化bean實(shí)例前調(diào)用。此注釋僅對(duì)有狀態(tài)會(huì)話bean可用。

  • @PostActivate:當(dāng)客戶端再次使用被鈍化的有狀態(tài)會(huì)話bean時(shí),將創(chuàng)建一個(gè)新的實(shí)例,并重新保存bean狀態(tài)。標(biāo)記此注釋的方法在準(zhǔn)備激活bean實(shí)例時(shí)調(diào)用。此注釋僅對(duì)有狀態(tài)會(huì)話bean可用。

  • @Init:此注釋為有狀態(tài)會(huì)話bean指定初始化方法。它與@PostConstruct注釋的不同點(diǎn)在于,在有狀態(tài)會(huì)話bean中,多個(gè)方法可以被標(biāo)記為@Init。但是,每個(gè)bean實(shí)例只能有一個(gè)被調(diào)用的@Init方法。EJB 3.0容器根據(jù)bean的創(chuàng)建方式確定要調(diào)用的@Init方法(請(qǐng)參閱EJB 3.0規(guī)范以獲取詳細(xì)信息)。@PostConstruct方法在@Init方法之后調(diào)用。

  另一個(gè)用于有狀態(tài)會(huì)話bean的生命周期方法注釋是@Remove標(biāo)記。它不是一個(gè)回調(diào)方法,因?yàn)閼?yīng)用程序(而不是容器)在bean存根上調(diào)用@Remove方法以移除容器對(duì)象池中的bean實(shí)例。

實(shí)體bean

  EJB 3.0實(shí)體是輕量級(jí)持久性域?qū)ο?。?shí)體bean使用@Entity注釋標(biāo)記,實(shí)體bean中所有未使用@Transient注釋標(biāo)記的屬性/字段都被視為持久性的。實(shí)體bean持久性字段通過JavaBean樣式的屬性公開,或者僅作為公共/受保護(hù)Java類字段。

  實(shí)體bean可使用helper類表示實(shí)體bean狀態(tài),但這些類的實(shí)例不具有持久性。相反,其存在與擁有實(shí)體bean的實(shí)例密切相關(guān);同時(shí)這些對(duì)象不可跨實(shí)體共享。

主接口

  實(shí)體bean不需要主接口。

業(yè)務(wù)接口

  實(shí)體bean不需要業(yè)務(wù)接口。它們都是可選的。

實(shí)體類

  • 實(shí)體類必須使用實(shí)體注釋進(jìn)行注釋,或者在XML描述符中表示為實(shí)體。

  • 實(shí)體類必須具有一個(gè)無參數(shù)的構(gòu)造函數(shù)。同時(shí)實(shí)體類還可以具有其他構(gòu)造函數(shù)。

  • 無參數(shù)的構(gòu)造函數(shù)必須是公共的或受保護(hù)的。

持久性字段或?qū)傩?/h4>

  對(duì)于單值持久性屬性,方法簽名為:

  • T getProperty()

  • void setProperty(T t)

代碼示例

  從以下的代碼示例中可以發(fā)現(xiàn),實(shí)體bean是使用@Entity標(biāo)記注釋的。在該示例中,有一些成員變量以及與它們對(duì)應(yīng)的getter和setter方法。該代碼示例還顯示了如何注釋CMR關(guān)系。

  一對(duì)多關(guān)系使用@OneToMany標(biāo)記顯示。在此示例中,Customer bean具有與Orderscode> bean的一對(duì)多關(guān)系(一個(gè)客戶可以具有多個(gè)訂單)。

  類似地,Customercode>具有與Phonescode> bean的多對(duì)多關(guān)系。一些業(yè)務(wù)方法將在業(yè)務(wù)接口中定義并在bean中實(shí)現(xiàn),例如addPhone(),它用于添加電話記錄并將其與客戶相關(guān)聯(lián):

@Entity public class Customer implements Serializable { private Long id; private String name; private Address address; private Collection orders = new HashSet(); private Set phones = new HashSet(); // No-arg constructor public Customer() {} @Id public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } @OneToMany public Collection getOrders() { return orders; } public void setOrders(Collection orders) { this.orders = orders; } @ManyToMany public Set getPhones() { return phones; } public void setPhones(Set phones) { this.phones = phones; } // Business method to add a phone number to the customer public void addPhone(PhoneNumber phone) { this.getPhones().add(phone); // Set the phone‘s ref to this customer phone.setCustomer(this); } } }

消息驅(qū)動(dòng)bean

  現(xiàn)在我們來看最后一種EJB類型:消息驅(qū)動(dòng)bean。

業(yè)務(wù)接口

  消息驅(qū)動(dòng)bean (MDB)業(yè)務(wù)接口是由用于bean的消息類型確定的消息監(jiān)聽器接口。該接口為javax.jms.MessageListener。消息驅(qū)動(dòng)bean必須為其支持的消息傳遞類型實(shí)現(xiàn)適當(dāng)?shù)南⒈O(jiān)聽器接口,或者必須使用@MessageDriven注釋或部署描述符指定其消息監(jiān)聽器接口。

bean類

  在EJB 3.0中,MDB bean類使用@MessageDriven注釋進(jìn)行注釋,該注釋指定此MDB監(jiān)視的消息隊(duì)列(如隊(duì)列/mdb)。

  Bean類需要實(shí)現(xiàn)MessageListener接口,該接口僅定義了一個(gè)onMessage()方法。當(dāng)消息到達(dá)此MDB監(jiān)視的隊(duì)列中時(shí),容器將調(diào)用bean類的onMessage()方法,并將傳入消息作為調(diào)用參數(shù)傳入。

  在我們的示例中,TraderBean.onMessage()方法檢索消息正文,分析出參數(shù),執(zhí)行交易,并將結(jié)果保存到靜態(tài)數(shù)據(jù)管理器類中。服務(wù)請(qǐng)求消息上的sent時(shí)間戳充當(dāng)計(jì)算記錄的惟一ID(對(duì)低流量Web站點(diǎn)效果很好)。check.jsp JSP頁(yè)面基于消息ID獲取并顯示計(jì)算記錄:

@MessageDriven(activateConfig = { @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"), @ActivationConfigProperty(propertyName="destination", propertyValue="queue/mdb") }) public class TraderBean implements MessageListener { public void o-nMessage (Message msg) { try { TextMessage tmsg = (TextMessage) msg; Timestamp sent = new Timestamp(tmsg.getLongProperty("sent")); StringTokenizer st = new StringTokenizer(tmsg.getText(), ","); buy ("SNPS",1000); RecordManager.addRecord (sent, "BUY SUCCESSFUL"); } catch (Exception e) { e.printStackTrace (); } } // ... ... }

發(fā)送消息

  要使用消息驅(qū)動(dòng)bean,客戶端(如此例中的JSP頁(yè)面、trader.jsp)需要使用標(biāo)準(zhǔn)JMS API通過隊(duì)列名稱(隊(duì)列/mdb)的方式獲取MDB的目標(biāo)消息隊(duì)列,然后將消息發(fā)送到該隊(duì)列:

try { InitialContext ctx = new InitialContext(); queue = (Queue) ctx.lookup("queue/mdb"); QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("ConnectionFactory"); cnn = factory.createQueueConnection(); sess = cnn.createQueueSession( false,QueueSession.AUTO_ACKNOWLEDGE); } catch (Exception e) { e.printStackTrace (); } TextMessage msg = sess.createTextMessage("SNPS",1000); sender = sess.createSender(queue); sender.send(msg);

消息驅(qū)動(dòng)Bean的回調(diào)

  支持以下的消息驅(qū)動(dòng)bean生命周期事件回調(diào):

  • PostConstruct

  • PreDestroy

如何對(duì)待以前的實(shí)體模型?

  出于兼容性方面的原因,以前的實(shí)體模型將仍然作為EJB的一部分,并將始終是EJB的一部分。專家組目前正在查看EJB 3.0中許多可能對(duì)使用以前的編程模型的人有用的新特性,并在考慮使其對(duì)那些使用以前的編程模型的人可用。EJB 3.0計(jì)劃擴(kuò)展EJB-QL以用于EJB 2.1樣式的CMP實(shí)體bean。因此,如果您希望繼續(xù)使用以前的編程模型,那么完全可以這么做,并同時(shí)使用某些新功能。

結(jié)束語(yǔ)

  EJB 3.0通過簡(jiǎn)化開發(fā)、推動(dòng)測(cè)試驅(qū)動(dòng)開發(fā)和更多地關(guān)注簡(jiǎn)單傳統(tǒng)Java對(duì)象(POJO)(而非復(fù)雜API),從而向前跨越了一大步,使EJB編程體驗(yàn)近乎于一件樂事。本文未詳細(xì)介紹的一個(gè)重要方面是規(guī)范中定義的新持久性框架。有關(guān)詳細(xì)信息,請(qǐng)查看EJB 3.0 API規(guī)范并下載EJB 3.0持久性文檔。

  BEA Systems公司在其BEA WebLogic Server中積極致力于其EJB3實(shí)現(xiàn)策略。一旦確定,關(guān)于實(shí)現(xiàn)和時(shí)間安排的詳細(xì)信息就會(huì)在dev2dev上提供。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
EJB3.0規(guī)范解讀
Java面試題集
Java面試題
EJB 3.0簡(jiǎn)介
EJB
Enterprise JavaBeans導(dǎo)論
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服