實體bean的內外存交換 現在應該來看看javax.ejb.EntityBean接口。 public interface javax.ejb.EntityBean extends EnterpriseBean { public void ejbActivate() throws RemoteException; public void ejbPassivate() throws RemoteException; public void ejbRemove() throws RemoteException,RemoveException; public void setEntityContext(EntityContext ctx) throws RemoteException; public void unsetEntityContext() throws RemoteException; public void ejbLoad() throws RemoteException; public void ejbStore() throws RemoteException; } 活化和鈍化的過程與會話bean類似。然而,不在事務中的實體bean是無狀態的;其狀態總是和底層的數據同步的。如果我們象鈍化會話bean那樣鈍化實體bean,則當鈍化無狀態實體bean時只會刪除它。但是因為容器調用finder方法需要匿名的實體bean,容器可能為此把不活動的實體bean鈍化到一個私有內存池中。一旦從EJBObject中刪除實體bean,則同時刪除了標識符(主鍵關聯)。 當客戶端調用沒有相關的實體bean的EJBObject的商業方法時,容器就可能用這個內存池重新分配實體bean. 注意這個內存池中的bean沒有標識,可以被任何EJBObject重用。容器可以可以不維護任何有EJBObject的實體bean,除非有一個商業方法在通過EJBObject被調用。如果實體bean在事務中則需保持其與EJBObject的關聯。 自管理的持久性 因為實體bean代表底層的數據,因此我們需要把數據從數據從數據庫中取出然後放在bean中。當容器第一次把一個實體bean的實例與EJBObject關聯時,它就開始了一個事務並調用了這個bean的ejbLoad()方法。在這個方法中開發者必須提供從數據庫中取出正確的數據並把它放在bean中。當容器將要提交一個事務它首先調用bean的ejbStrore()方法。這個方法負責向數據庫中回寫數據。我們稱之為自管理持久性,因為bean方法中的代碼提供了這種同步。 當ejbLoad()方法完成時,bean有可能與底層數據庫不一致。商業方法的調用觸發了與EJBObject關聯的bean的分配,然後在事務中執行的ejbLoad()必須在部署描述符中聲明。根據接收到的方法調用請求,EJBObject和容器一起建立一個事務上下文。容器分配EJBObject的bean並調用bean的ejbLoad()方法。這個方法現在運行在事務上下文中。這個事務上下文傳遞給數據庫,根據部署描述符中指定的孤立性級別,這個事務鎖定數據庫中被訪問的數據。 只要事務上下文活動,數據庫中的數據就一直保持鎖定狀態。當客戶端或容器提交事務時,容器首先調用bean的ejbStore()方法,把bean中的數據回寫到數據庫中。 相應的數據庫記錄在ejbLoad()和ejbStore()間保持鎖定保證了bean和數據庫間的同步。其間可以進行不同的商業方法調用。而且,ejbLoad()和ejbStore()明確地區分了事務邊界,事務中可以進行任何商業方法調用。事務的持續時間由部署描述符決定,也可能由客戶端決定。注意不必使用ejbActivate()和ejbPassivate()方法來執行與數據庫間的同步。 容器管理的持久性 如果部署描述符聲明bean使用容器管理的持久性,則不用ejbLoad()和ejbStore()來訪問數據庫。容器會把數據從數據庫中導入到bean中,然後調用bean的ejbLoad()方法來完成從數據庫中接收數據。 同樣地,容器調用bean的ejbStore()方法來完成把數據回寫到數據庫中。這些方法實際上沒有執行任何數據庫操作。當開發商用復雜的工具來提供容器管理持久性時,如自動產生能進行對象--關系映射的實體bean類,規范規定了廠商必須提供的容器管理實體持久性的最小需求集。 部署描述符可以指定bean的一個public域來實現與數據庫列簡單映射。容器使用部署描述符讀出bean的這個public域並寫到相應的列,或從數據庫列中讀出數據寫到public域中。容器管理的持久性對EJB開發者來說是非常好的服務,且不需對象--關系影射等其他復雜的機制,開發者會發現它比自管理的持久性更有效率。 部署描述符 區分EJB開發的角色 EJB開發中兩個主要的角色是bean開發者和bean部署者。有很多屬性開發者不能預知,如數據庫的網絡地址,使用的數據庫驅動程序等等。部署描述符作為由開發定義的特性表,由部署者添入正確的值。部署描述符有標准的格式,在開發和部署環境中是可移植的,甚至在不同EJB平台間也是可移植的。 Enterprise bean的行為控制 除了為開發和部署的協同提供一個標准的屬性單,部署描述符也應包含bean應如何執行有關事務和安全的細節信息。一些如訪問控制鏈(ACL)等屬性,也應該由部署者來調整以保證適當的用戶能在運行時使用bean.其它屬性,如事務信息,有可能完全由開發者指定,因為一般由開發者創建數據庫訪問代碼,並熟知bean的方法應如何運行事務。定義部署描述符 部署描述符是一個標准的Java類。創建一個實例,導入數據,然後串行化。這個串行化的部署描述符放在一個jar文件中並和enterprise bean類一起送到部署環境。部署者讀取這個串行化的部署描述符,可能修改一些屬性值,然後使用這個修改後的部署描述符來安裝enterprise bean. 下面是部署描述符的一部分內容。它是兩個其它的部署描述符類的超類。實際上超類是描述這個bean的描述符。 Javax.ejb.deployment.DeploymentDescriptor ·bean home name ·bean class name ·home interface class name ·remote interface class name ·environment propertIEs ·control descriptors ·Access control list DeploymentDescriptor有兩個子類: javax.ejb.deployment.SessionDescriptor ·state management type ·session timeout javax.ejb.deployment.EntityDescriptor ·list of ocntainer-managed fIElds ·primary key class name 描述符為實體bean和每個方法定義了事務和安全屬性。這些對象的一個數組在DeploymentDescriptor中指定。 Javax.ejb.deployment.ControlDescriptor ·transaction isolation level ·Method object to which this descriptor applIEs ·run-as mode(for odentity mapping) ·run-as identity(for identity mapping) ·transaction attribute 部署一個enterprise bean時,分配對應的描述符,然後初始化,串行化,再將其與enterprise bean類一起放入到一個jar文件中。不同廠商在定義部署描述符時可能有不同的方式。例如,一個廠商可能使用文本方式,而另一廠商可能提供圖形工具。但最後結果的部署描述符是一個標准的格式,並且在不同平台間是可移植的。 EJB Jar文件 為了包裝一個enterprise bean,bean的類,接口和串行化的部署描述符放在一個jar文件中。這個jar文件必須有一個manifest文件的入口以聲明一個enterprise bean的部署描述符。 Name:AccountDD.ser Enterprise-Bean:true 在manifest中作為enterprise bean列出的是部署描述符,而不是bean類。部署描述符除了定義enterprise bean,還提供jar文件中所有文件的完整描述。開發者不必關心EJB jar文件的創建。廠商應該提供一個工具來幫助開發者創建部署描述符,然後把所有必須的文件打包進一個jar文件中。