Entity Bean(1)
一、前言
從前面幾期的介紹,我們知道Enterprise JavaBean(EJB)是J2EE架構(gòu)中用來(lái)實(shí)作business tier的技術(shù)。就J2EE Design Pattern而言,business tier代表了MVC pattern中的model,model負(fù)責(zé)處理的是對(duì)business最重要的domain objects與business logic。在這個(gè)脈絡(luò)下,J2EE Design Pattern建議我們使用session bean與message-driven bean實(shí)作business logic,而以entity bean實(shí)作domain objects。透過(guò)使用entity bean,我們以物件模式塑模(modeling)business data,這不僅使我們可以運(yùn)用物件導(dǎo)向程式設(shè)計(jì)的優(yōu)點(diǎn),也得以享受EJB Container提供的各種背景服務(wù)(如Persistence、Transaction、Security、Concurrency等)。本期及下一期我們將就entity bean的種類(lèi)、生命週期、程式碼的實(shí)作、以及client端的使用對(duì)entity bean做一初步的介紹。後續(xù)的幾期我們將介紹entity bean的進(jìn)階功能與相關(guān)設(shè)定。
二、Entity bean的種類(lèi)
就資料保存(Data Persistency)的觀點(diǎn)而言,entity bean以物件模式保存資料只是各種資料保存模式中的一種。在實(shí)作中,entity bean除了接收來(lái)自clent端的資料外,主要還是從所謂的Enterprise Information System tier(EIS)取得既存的資料並將處理後的資料儲(chǔ)存在EIS tier,而關(guān)聯(lián)式資料庫(kù)(RDBM)則是目前最為普遍的EIS tier技術(shù)。面對(duì)不同的資料保存模式,如何在不同的tier之間維持資料的一致性與完整性(Data Interity)是個(gè)重要的課題。針對(duì)這個(gè)問(wèn)題,EJB提供了兩種技術(shù):CMP bean與BMP bean。BMP bean(Bean-Managed Persistence)將有關(guān)資料保存的工作交由開(kāi)發(fā)人員負(fù)責(zé),開(kāi)發(fā)人員必須熟悉EJB Container呼叫call back 方法與其他bean life-cycle方法的時(shí)機(jī)與方式,並在BMP bean中實(shí)作與存取資料庫(kù)有關(guān)的程式碼。而CMP bean(Container-Managed Persistence)則將有關(guān)資料保存的工作交由EJB Container處理,開(kāi)發(fā)人員不需要在entity bean中編寫(xiě)有關(guān)存取資料庫(kù)的程式碼,而只需要在部署描述子(deployment descriptor)中定義好entity bean與資料庫(kù)之間的對(duì)應(yīng)(mappings),在部署階段部署工具會(huì)自動(dòng)產(chǎn)生相關(guān)的JDBC程式碼。這麼做的好處首先在於實(shí)際部署時(shí)得以動(dòng)態(tài)產(chǎn)生entity bean與data sources之間的繫結(jié);更重要的是,它使開(kāi)發(fā)人員得以專(zhuān)注於以物件導(dǎo)向的思維模式集中心力於business logic上。
在EJB 1.1規(guī)格書(shū)中並沒(méi)有對(duì)CMP如何與資料庫(kù)schema之間的mappings提出一個(gè)標(biāo)準(zhǔn)的規(guī)範(fàn),此外對(duì)於如何建立多個(gè)entity bean之間的關(guān)係,如何尋找與定位(finding and locating)entity bean的做法亦付之闕如。但在EJB 2.0規(guī)格書(shū)中則對(duì)CMP做出了重大的改進(jìn),包括標(biāo)準(zhǔn)的Query Language(QL)、Container-Managed Relationships(CMR)等,我們將在下期作進(jìn)一步的介紹。以下是有助於選擇CMP或BMP的因素:
1. CMP比BMP易於開(kāi)發(fā)維護(hù),EJB Container會(huì)對(duì)資料存取的過(guò)程做最佳化。
2. BMP適用於對(duì)效能要求較高與較為複雜的應(yīng)用程式,但若開(kāi)發(fā)不當(dāng),則很容易拖垮系統(tǒng)的效能。
3. CMP不支援較為複雜的SQL語(yǔ)法,如在where子句中對(duì)日期與時(shí)間的比較。
4. CMP支援的data sources類(lèi)型受container provider的限制。此外目前的CMP並不支援非JDBC的data sources。
5. 如果要使用CMR,則必須使用CMP。
三、Entity bean的生命週期
EJB Container運(yùn)用集區(qū)(Pool)的概念來(lái)管理entity bean以妥善運(yùn)用系統(tǒng)資源並增進(jìn)系統(tǒng)效能。根據(jù)entity bean是否被放入集區(qū)與是否與EJB Object結(jié)合,entity bean有三種狀態(tài):分別是Not Exist State、Pooled State、Ready State。下圖展示了EJB Container如何藉由呼叫bean class的call back與life-cycle方法在這三種狀態(tài)間轉(zhuǎn)換(下圖引用自Richard Monson-Haefel, Enterprise JavaBeans, 3rd Edition, O’Reilly,Page 308, Figure 11-2):
1. Not Exist State
在這個(gè)狀態(tài)中,entity bean可視為一堆檔案的集合,這些檔案包括部署描述子、component interface,以及所有在部署階段產(chǎn)生的輔助classes。此時(shí)不存在任何entity bean instance。
2. Pooled State
當(dāng)EJB Server啟動(dòng)後,它會(huì)讀取相關(guān)檔案,產(chǎn)生一些entity bean的instance。在產(chǎn)生entity bean instance後,EJB Container會(huì)呼叫entity bean的setEntityContext()方法,將EntityContext物件賦予entity bean instance,EntityContext物件記載著該entity bean instance所在的EJB Container的狀態(tài)。在entity bean instance被賦予EntityContext後,就被放到集區(qū)中,進(jìn)入Pooled State。此時(shí)的entity bean只有預(yù)設(shè)值,並不代表資料庫(kù)裡的任何資料。
有幾種情況可以使得在Pooled State中的entity bean instance離開(kāi)集區(qū)並被資源回收。首先,EJB Server可視需要增加或減少集區(qū)中的entity bean instance,以有效利用系統(tǒng)資源並在效能上有較佳表現(xiàn)。其次,當(dāng)停止EJB Server時(shí),EJB Container也會(huì)釋放所有在集區(qū)中的bean instance。最後,當(dāng)entity bean instance出現(xiàn)不可修復(fù)的錯(cuò)誤時(shí),EJB Container也會(huì)將之移出集區(qū),並以集區(qū)中其他entity bean instance取代之。
在entity bean instance被移出集區(qū)之後與被資源回收之前,EJB Container會(huì)呼叫其unsetEntityContext()方法,以通知該entity bean instance即將被毀滅。
3. Ready State
當(dāng)client端呼叫entity bean的home interface上的create()方法時(shí),EJB Server會(huì)產(chǎn)生一個(gè)EJB Object,並從集區(qū)中取出一個(gè)entity bean與之結(jié)合,此時(shí)entity bean進(jìn)入Ready State。接著EJB Container會(huì)依序呼叫在entity bean instance上與create()對(duì)應(yīng)的ejbCreate()與ejbPostCreate()方法。當(dāng)ejbPostCreate()方法執(zhí)行完成後,create()方法會(huì)回傳一個(gè)EJB Object的reference給client端,此時(shí)entity bean instance與EJB Object就可以服務(wù)來(lái)自client端的請(qǐng)求。
前面介紹Pooled State時(shí)曾提到EJB Container為了有效利用系統(tǒng)資源,會(huì)視需要增加或減少集區(qū)中的entity bean instance,同樣地,EJB Container也會(huì)視需要在Pooled State與Ready State之間移動(dòng)entity bean instance。Entity bean instance從Ready State移至Pooled State叫做Passivation過(guò)程,從Pooled State移至Ready State則叫做Activation過(guò)程。在Passivation過(guò)程中,EJB Container會(huì)呼叫entity bean的ejbStore()方法,將目前entity bean instance的資料寫(xiě)回資料庫(kù),再呼叫entity bean的ejbPassivate()方法通知該entity bean instance其即將被移回Pooled State。ejbPassivate()方法執(zhí)行完成後,entity bean instance就與EJB Object分離並回到Pooled State。
Activation過(guò)程預(yù)設(shè)了某entity bean先前的Passivation過(guò)程。在Passivation過(guò)程結(jié)束後,原先與EJB Object結(jié)合的entity bean instance回到Pooled State,而EJB Object則維持其與client端的連線。一旦client再度呼叫EJB Object上的方法時(shí),EJB Container就從集區(qū)中任意取出一entity bean instance與既存的EJB Object結(jié)合,繼續(xù)服務(wù)來(lái)自client端的請(qǐng)求。在這過(guò)程中,EJB Container呼叫entity bean的ejbActivate()方法,通知該entity bean instance準(zhǔn)備更新來(lái)自資料庫(kù)的資料,再呼叫entity bean的ejbLoad()方法通知該entity bean instance資料已經(jīng)重新寫(xiě)入,準(zhǔn)備服務(wù)來(lái)自client端的請(qǐng)求。
最後一種從Ready State將entity bean instance移回Pooled State的情況是client端呼叫EJB Object或EJB Home上相關(guān)的的remove方法時(shí),EJB Container會(huì)呼叫entity bean上的ejbRemove()方法,此時(shí)系統(tǒng)會(huì)刪除資料庫(kù)中與該entity bean instance相對(duì)應(yīng)的資料。ejbRemove()方法執(zhí)行完成後,該entity bean instance就被移回Pooled State。
posted on 2008-12-04 11:30 paulwong 閱讀(298) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): J2EE