首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

EJB 遠程調用原理深度剖析:從 RMI 到雙層 Stub/Skeleton 鏈路

     編輯:Java 程式設計入門

核心架構:10 個類檔案的角色分工

一個 EJB 遠程調用涉及 10 個類,遠超普通 RMI 的 4 個:

類別用戶編寫產生時機說明
Bean 類✓開發期業務邏輯實現
Bean WebLogic 實現類✗ejbc 編譯期容器生成,攔截生命週期
Remote 介面✓開發期客戶端調用契約
Remote WebLogic 實現類 (EOImpl)✗ejbc 編譯期委託 Bean 實現類
EOImpl Stub✗部署期動態生成客戶端代理,序列化傳遞
EOImpl Skeleton✗部署期動態生成伺服器端接收調用
Home 介面✓開發期生命週期管理契約
Home WebLogic 實現類 (HomeImpl)✗ejbc 編譯期實現 create/find 等
HomeImpl Stub✗部署期動態生成JNDI 查詢返回的代理
HomeImpl Skeleton✗部署期動態生成伺服器端處理 Home 調用

關鍵差異:EJB 的 Stub 由伺服器動態生成並序列化傳給客戶端,客戶端無需預先部署 Stub 類。

完整調用鏈路:兩次 RMI 循環

第一階段:獲取 Home Stub(JNDI 查詢)

  1. 客戶端 ctx.lookup("Hello")
  2. 伺服器 JNDI 綁定的是 HelloBean_HomeImpl_WLStub 實例
  3. 伺服器序列化 Stub 實例傳回客戶端
  4. 客戶端獲得 Home 介面引用(實為 HomeImpl Stub)

第二階段:create() 創建 EJB 實例

  1. 客戶端呼叫 home.create() → 實際調用 HomeImpl_WLStub.create()
  2. RMI 循環 1:Stub → 網路 → HomeImpl_WLSkeleton → HomeImpl.create()
  3. HomeImpl.create() 呼叫 BeanImpl.ejbCreate() 創建 Bean 實例
  4. HomeImpl 創建 EOImpl_WLStub 實例,序列化傳回客戶端

第三階段:業務方法調用

  1. 客戶端呼叫 remote.helloWorld() → 實際調用 EOImpl_WLStub.helloWorld()
  2. RMI 循環 2:Stub → 網路 → EOImpl_WLSkeleton → EOImpl.helloWorld()
  3. EOImpl 委託 BeanImpl.helloWorld()(用戶代碼終於被執行!)

關鍵設計洞察

1. 雙層代理模式

  • Home 層:管理生命週期,返回 Remote Stub
  • Remote 層:業務代理,委託 Bean 實現類

2. 伺服器端也有「代理」

HomeImpl 在伺服器端充當 BeanImpl 的代理(非 RMI,進程內調用),EOImpl 同理。容器透過這層攔截實現事務、安全、持久化等企業級服務。

3. 介面導向編程的極致體現

客戶端代碼只依賴 Home.class、Remote.class,完全屏蔽實現類、Stub、Skeleton、容器生成類。部署時動態生成 Stub/Skeleton 字節碼,實現「零客戶端部署」。

WebLogic 具體類命名對照

// 用戶編寫
HelloBean           // Bean 類
HelloHome           // Home 介面
Hello               // Remote 介面

// ejbc 生成(打包在 EJB JAR)
HelloBean_Impl
HelloBean_HomeImpl
HelloBean_EOImpl

// 部署期動態生成(不見類文件)
HelloBean_HomeImpl_WLStub / _WLSkeleton
HelloBean_EOImpl_WLStub / _WLSkeleton

客戶端驗證代碼

HelloHome home = (HelloHome) PortableRemoteObject.narrow(
    ctx.lookup("Hello"), HelloHome.class);
System.out.println(home); // 輸出: HelloBean_HomeImpl_WLStub@18c458

Hello remote = home.create();
System.out.println(remote); // 輸出: HelloBean_EOImpl_WLStub@8fa0d1

remote.helloWorld(); // 觸發第二次 RMI 循環

總結

EJB 遠程調用本質是雙層 RMI 代理鏈路:Home Stub 創建 Remote Stub,Remote Stub 委託業務邏輯。容器生成的實現類與動態 Stub/Skeleton 構成攔截層,將企業級關注點(事務、安全、資源管理)與業務邏輯分離。雖然 EJB 2.x 已被輕量級框架取代,但其分層代理、介面契約、伺服器端動態代理生成等設計思想,深刻影響了後續的 Spring、gRPC、微服務側車等架構演進。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved