class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
myComponent
com.mycom.MyComponent
這些看似簡單的代碼背后隱藏了很多復雜的處理,比如默默工作的Spring AOP框架,我們甚至不必知道這些概念,一樣可以享用它的結果。Bean myComponent 的定義中創建了一個該EJB組件的代理對象,它實現了業務方法接口。這個EJB組件的 本地Home對象在啟動的時候就被放到了緩存中,所以只需要執行一次JNDI查找即可。 每當EJB組件被調用的時候,這個代理對象就調用本地EJB組件的create方法,并調用 該EJB組件的相應的業務方法。
在Bean myController的定義中,控制器類的屬性 myController的值被設置為上面代理對象。
這樣的EJB組件訪問方式大大簡化了應用程序代碼:Web層(或其他EJB客戶端) 的代碼不再依賴于EJB組件的使用。如果我們想把這個EJB的引用替換為一個POJO, 或者是模擬用的對象或其他測試組件,我們只需要簡單地修改Bean myComponent 的定義中僅僅一行Java代碼,此外,我們也不再需要在應用程序中編寫任何JNDI查找 或其它EJB相關的代碼。
評測和實際應用中的經驗表明,這種方式的性能負荷極小,(盡管其中 使用了反射方式以調用目標EJB組件的方法),通常的使用中我們幾乎覺察不出。請記住 我們并不想頻繁地調用EJB組件的底層方法,雖然如此,有些性能代價是與應用服務器 中EJB的基礎框架相關的。
關于JNDI查找有一點需要注意。在Bean容器中,這個類通常最好用作單件 (沒理由使之成為原型)。不過,如果這個Bean容器會預先實例化單件(類似XML ApplicationContext的變體的行為),如果在EJB容器載入目標EJB前載入bean容器, 我們就可能會遇到問題。因為JNDI查找會在該類的init方法中被執行并且緩存結果, 這樣就導致該EJB不能被綁定到目標位置。解決方案就是不要預先實例化這個工廠對象, 而允許它在第一次用到的時候再創建,在XML容器中,這是通過屬性 lazy-init來控制的。
盡管大部分Spring的用戶不會對這些感興趣,但那些對EJB進行AOP的具體應用 的用戶則會想看看LocalSlsbInvokerInterceptor。
1.3. 訪問遠程的無狀態Session Bean(SLSB)
基本上訪問遠程EJB與訪問本地EJB差別不大,除了前者使用的是 SimpleRemoteStatelessSessionProxyFactoryBean。當然, 無論是否使用Spring,遠程調用的語義都相同,不過,對于使用的場景和錯誤處理 來說,調用另外一臺計算機上不同虛擬機中的對象的方法其處理有所不同。
與不使用Spring方式的EJB客戶端相比,Spring的EJB客戶端有一個額外的 好處。通常如果客戶端代碼隨意在本地EJB和遠程EJB的調用之間來回切換,就有 一個問題。這是因為遠程接口的方法需要聲明其會拋出RemoteException ,然后客戶端代碼必須處理這種異常,但是本地接口的方法卻不需要這樣。 如果要把針對本地EJB的代碼改為訪問遠程EJB,就需要修改客戶端代碼,增加 對RemoteException的處理,反之就需要去掉這樣的 異常處理。使用Spring 的遠程EJB代理,我們就不再需要在業務方法接口和EJB的 代碼實現中聲明會拋出RemoteException,而是定義一個 相似的遠程接口,唯一不同就是它拋出的是RemoteAccessException, 然后交給代理對象去動態的協調這兩個接口。也就是說,客戶端代碼不再需要與 RemoteException這個顯式(checked)異常打交道,實際運行中 所有拋出的異常RemoteException都會被捕獲并轉換成一個 隱式(non-checked)的RemoteAccessException,它是 RuntimeException的一個子類。這樣目標服務端就可以 在本地EJB或遠程EJB(甚至POJO)之間隨意地切換,客戶端不再需要關心甚至 根本不會覺察到這種切換。當然,這些都是可選的,我們并不阻止在業務接口中聲明 異常RemoteExceptions。
2. 使用Spring提供的輔助類實現EJB組件
Spring也提供了一些輔助類來為EJB組件的實現提供便利。它們是為了倡導一些 好的實踐經驗,比如把業務邏輯放在在EJB層之后的POJO中實現,只把事務隔離和 遠程調用這些職責留給EJB。
要實現一個無狀態或有狀態的Session Bean,或消息驅動Bean,我們的實現 可以繼承分別繼承AbstractStatelessSessionBean, AbstractStatefulSessionBean,和 AbstractMessageDrivenBean/AbstractJmsMessageDrivenBean
考慮這個例子:我們把無狀態Session Bean的實現委托給普通的Java服務對象。 業務接口的定義如下:
public interface MyComponent {
public void myMethod(...);
...
}
這是簡單Java對象實現方式的類:
文章來源于領測軟件測試網 http://www.kjueaiud.com/