EJB呼叫原理分析

2021-05-22 06:00:23 字數 3601 閱讀 8044

hello h = new hello_stub();

h.getstring();

我們不會這樣寫:

hello_stub h = new hello_stub();

h.getstring();

因為使用介面適用性更廣,就算更換了介面實現類,也不需要更改**。因此客戶端需要hello.class和hello_stub.class這兩個檔案。

但是對於ejb來說,就不需要hello_stub.class,因為伺服器會傳送給它,但是hello.class檔案客戶端是省不了的,必須有。表面上我們的客戶端**在操縱hello,但別忘記了hello只是乙個介面,抽象的,實質上是在操縱hello_stub。

拿weblogic上的ejb舉例子,10個class分別是:

bean類:hellobean (使用者編寫)

bean類的weblogic實現類:hellobean_impl (ejbc生成)

home介面:hellohome (使用者編寫)

home介面的weblogic實現類 ((hello bean))_homeimpl(ejbc生成)

home介面的weblogic實現類的stub類 ((hello bean))_homeimpl_wlstub(部署的時候動態生成位元組碼)

home介面的weblogic實現類的skeleton類 ((hello bean))_homeimpl_wlskeleton(部署的時候動態生成位元組碼)

remote介面:hello (使用者編寫)

remote介面的weblogic實現類 ((hello bean))_eoimpl(ejbc生成)

remote介面的weblogic實現類的stub類 ((hello bean))_eoimpl_wlstub(部署的時候動態生成位元組碼)

remote介面的weblogic實現類的skeleton類 ((hello bean))_eoimpl_wlskeleton(部署的時候動態生成位元組碼)

客戶端只需要hello.class和hellohome.class這兩個檔案。

((hello home)) home = (home) 

((portable remote object)).narrow(ctx.lookup("hello"),

((hello home)).class);

這一行**是從jndi獲得home介面,但是請記住!介面是抽象的,那麼home這個物件到底是什麼類的物件例項呢?很簡單,用tostring()輸出看一下就明白了,下面一行是輸出結果:

((hello bean))_homeimpl_wlstub@18c458

這表明home這個通過從伺服器的jndi樹上查詢獲得的物件實際上是hellobean_homeimpl_wlstub類的乙個例項。

接下來客戶端**:

hello h = home.create()

同樣hello只是乙個抽象的介面,那麼h物件是什麼東西呢?列印一下:

((hello bean))_eoimpl_wlstub@8fa0d1

原來是hellobean_eoimpl_wlstub的乙個物件例項。

用這個例子來簡述一遍ejb呼叫過程:

首先客戶端jndi查詢,服務端jndi樹上hello這個名字實際上繫結的物件是hellobean_homeimpl_wlstub,所以服務端將建立hellobean_homeimpl_wlstub的乙個物件例項,序列化返回給客戶端。

於是客戶端得到home物件,表面上是得到hellohome介面的例項,實際上是進行了一次遠端呼叫得到了hellobean_homeimpl_wlstub類的物件例項,別忘記了hellobean_homeimpl_wlstub也實現了hellohome介面。

然後home.create()實質上就是hellobean_homeimpl_wlstub.create(),該方法將傳送資訊給hellobean_homeimpl_wlskeleton,而hellobean_homeimpl_wlskeleton接受到資訊後,再去呼叫hellobean_homeimpl的create方法,至此完成第1次完整的rmi迴圈。

注意在這次rmi迴圈過程中,遠端物件是hellobean_homeimpl,遠端物件的介面是hellohome,物件的stub是hellobean_homeimpl_wlstub,物件的skeleton是hellobean_homeimpl_wlskeleton。

然後hellobean_homeimpl再去呼叫hellobean_impl的ejbcreate方法,而hellobean_impl的ejbcreate方法將負責建立或者分配乙個bean例項,並且建立乙個hellobean_eoimpl_wlstub的物件例項。

這一步比較有趣的是,在前一步rmi迴圈中,遠端物件hellobean_homeimpl在客戶端有乙個**類hellobean_homeimpl_wlstub,但在這一步,hellobean_homeimpl自己卻充當了hellobean_impl的**類,只不過hellobean_homeimpl不在客戶端,而是在服務端,因此不進行rmi。

然後hellobean_eoimpl_wlstub的物件例項序列化返回給客戶端,這一步也很有趣,上次rmi過程,主角是hellobean_homeimpl和它的**類hellobean_homeimpl_wlstub,但這這一次換成了hellobean_eoimpl和它的**類hellobean_eoimpl_wlstub來玩了。

hello h = home.create();h.helloworld();

假設hello介面有乙個helloworld遠端方法,那麼表面上是在呼叫hello介面的helloworld方法,實際上是在呼叫hellobean_eoimpl_wlstub的helloworld方法。

然後hellobean_eoimpl_wlstub的helloworld方法將傳送資訊給伺服器上的hellobean_eoimpl_wlskeleton,而hellobean_eoimpl_wlskeleton收到資訊以後,再去呼叫hellobean_eoimpl的helloworld方法。至此,完成第2次完整的rmi迴圈過程。

在剛才hellobean_eoimpl是作為遠端物件被呼叫的,它的**類是hellobean_eoimpl_wlstub,但現在hellobean_eoimpl要作為hellobean_impl的**類了。現在hellobean_eoimpl去呼叫hellobean_impl的helloworld方法。注意!hellobean_impl繼承了hellobean,而hellobean中的helloworld方法是我們親自編寫的**,現在終於呼叫到了我們編寫的**了!

至此,一次ejb呼叫過程終於完成。在整個過程中,服務端主要要呼叫的類是hellobean_impl, hello bean?_homeimpl,hellobean_homeimpl_wlskeleton,hellobean_eoimpl,hellobean_eoimpl_wlskeleton。

客戶端主要呼叫的類是hellobean_homeimpl_wlstub,hellobean_eoimpl_wlstub,這兩個類在客戶端**中並不會直接出現,出現在**中的類是他們的介面hellohome和hello,因此客戶端需要這兩個介面檔案,而stub是伺服器傳送給他們的。

EJB3 0呼叫儲存過程

要呼叫儲存過程,我們可以通過 entitymanager 物件的 createnativequery 方法執行 sql 語句 注意 這裡說的是sql 語句,不是 ejb3 ql 呼叫儲存過程的 sql 格式如下 在 ejb3 中你可以呼叫的儲存過程有兩種 1 無返回值的儲存過程。2 返回值為 res...

乙個Ejb呼叫另乙個Ejb

乙個ejb呼叫另乙個ejb有兩種方法 第一是同個jndi 查詢 initialcontext ctx new initialcontext ihelloword helloworld ihelloword ctx.lookup helloworld remote 第二種 通過依賴注入 1 ejb i...

乙個Ejb呼叫另乙個Ejb

乙個ejb呼叫另乙個ejb有兩種方法 第一是同個jndi 查詢 initialcontext ctx new initialcontext ihelloword helloworld ihelloword ctx.lookup helloworld remote 第二種 通過依賴注入 1 ejb i...