以 HelloBean 為例,部署後生成的關鍵類:
HelloBean (用戶編寫)HelloBean_Impl (EJBC 生成,繼承 Bean)HelloHome (用戶編寫)HelloBean_HomeImpl (EJBC 生成)HelloBean_HomeImpl_WLStub (部署時動態生成字節碼)HelloBean_HomeImpl_WLSkeleton (部署時動態生成)Hello (用戶編寫)HelloBean_EOImpl (EJBC 生成,實現 Remote)HelloBean_EOImpl_WLStub (部署時動態生成)HelloBean_EOImpl_WLSkeleton (部署時動態生成)客戶端僅需 Hello.class、HelloHome.class 兩個接口文件。
HelloHome home = (HelloHome) PortableRemoteObject.narrow(
ctx.lookup("Hello"), HelloHome.class);
調用 home.toString() 輸出:HelloBean_HomeImpl_WLStub@18c458 —— 客戶端拿到的實際是 Home Stub 實例,而非服務端實現類。Stub 實現了 Home 接口,序列化傳遞給客戶端。
Hello h = home.create(); // 實際調用 HelloBean_HomeImpl_WLStub.create()
create()HelloBean_HomeImpl_WLSkeletonHelloBean_HomeImpl.create()HelloBean_HomeImpl.create() 內部調用 HelloBean_Impl.ejbCreate() 創建/分配 Bean 實例,並構造 HelloBean_EOImpl_WLStub 序列化返回客戶端。此過程在服務端內部完成,無網絡開銷(HomeImpl 充當 Bean_Impl 的本地代理)。
h.helloWorld(); // 實際調用 HelloBean_EOImpl_WLStub.helloWorld()
helloWorld()HelloBean_EOImpl_WLSkeletonHelloBean_EOImpl.helloWorld()HelloBean_EOImpl.helloWorld() 內部調用 HelloBean_Impl.helloWorld() —— 這才是開發者編寫的業務邏輯!
調用鏈總結:
Client Stub → Network → Server Skeleton → Server Impl → (Local Proxy) → Bean Impl → User Code
| 階段 | 遠程對象 | 接口 | Client Stub | Server Skeleton | Server Impl |
|---|---|---|---|---|---|
| JNDI Lookup | HomeImpl | HelloHome | HomeImpl_WLStub | HomeImpl_WLSkeleton | HomeImpl |
| create() | HomeImpl | HelloHome | HomeImpl_WLStub | HomeImpl_WLSkeleton | HomeImpl |
| Business Method | EOImpl | Hello | EOImpl_WLStub | EOImpl_WLSkeleton | EOImpl → Bean_Impl |
HelloHome, Hello)HomeImpl_WLStub, EOImpl_WLStub)