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...