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

J2EE 1.3 中移除 Service Locator 模式的資源快取機制

     編輯:Java 相關知識

緒論

Service Locator 是 J2EE 應用中常見的設計模式,透過封裝 JNDI 目錄服務查找程式碼,讓用戶端以資源名稱取得資源。傳統實作常包含資源快取以避免重複查找,這在 J2EE 1.2 運作良好,但在 J2EE 1.3 及後續版本中,快取會引入微妙且難以診斷的錯誤。因此,J2EE 1.3 應用的 Service Locator 實作不應包含資源快取。

JNDI 目錄服務回顧

Java Naming and Directory Interface (JNDI) 讓 Java 程式透過唯一名稱存取資源,屏蔽儲存位置、實作細節與提供者差異。JNDI 名稱採層次樹狀結構,J2EE 規範定義了標準子上下文(如 java:comp/env/jdbc 對應 JDBC 資料源)。應用程式伺服器建構自身 JNDI 樹,整合 JDBC、JMS 等資源,使元件能以統一方式存取本地或遠端資源,支援元件重用。

資源名稱映射與重載機制

J2EE 採雙重命名機制:

  • 資源參考名稱:程式碼使用的邏輯名稱(如 jdbc/AccountDB)。
  • JNDI 名稱:容器使用的實際名稱(如 jdbc/Cloudscape)。

部署時由管理員將參考名稱映射至 JNDI 名稱。J2EE 1.2 中資源名稱為全域,J2EE 1.3 引入元件級作用域:每個 EJB 或 Web 模組擁有獨立的資源名稱空間。這導致資源名稱重載——相同參考名稱在不同元件可映射至不同容器資源。例如 EmployeeBean 與 CustomerBean 均使用 jdbc/AccountDB,但部署時分別綁定至 jdbc/AccountEmployeeDS(完整權限)與 jdbc/AccountCustomerDS(唯讀權限),以滿足安全需求。

Service Locator 模式與快取陷阱

典型 Service Locator 以單例實作,內含 Map 快取資源查找結果。首次查找後存入快取,後續請求直接返回快取物件。此機制在 J2EE 1.2 全域名稱下無害,但在 J2EE 1.3 重載名稱下將導致嚴重錯誤:

  1. 首次請求來自 EmployeeBean,查找 jdbc/AccountDB 獲取 AccountEmployeeDS 並存入快取。
  2. 後續 CustomerBean 請求同名稱,Service Locator 直接返回快取的 AccountEmployeeDS,導致客戶端取得員工權限資料源,違反安全策略。

此錯誤極難偵測:若員工先登入,客戶端竊取機密權限;若客戶先登入,員工無法存取機密表單。錯誤僅在特定順序下出現,靜態程式碼分析無法發現。

執行期驗證實驗

作者透過兩個無狀態 Session Bean 驗證:

  • 無 Service Locator:直接 JNDI 查找,兩 Bean 取得不同資料源實例(OID 不同)。
  • 含快取 Service Locator:兩 Bean 取得相同資料源實例(OID 相同),第二個 Bean 使用錯誤資源。
  • 無快取 Service Locator:每次查找,兩 Bean 取得正確對應資源(OID 不同)。

解決方案:移除快取

為何曾需要快取? J2EE 1.2 時代 JNDI 查找效能較差,快取可提升效能。但 J2EE 1.3 容器已優化 JNDI 查找效能,快收益微乎其微。且快取改變了定位器行為,違反「正確性優於速度」原則。

替代方案分析:

  • 唯一資源名稱:強制每元件使用唯一名稱,避免重載,但命名繁瑣且阻礙資源共享。
  • 每元件類型獨立 Service Locator 實例:實作困難,難以管理儲存位置與 EJB 靜態變數限制。
  • 完全不使用 Service Locator:捨棄封裝優勢,得不償失。
  • 容器層級快取(最佳):由容器以唯一 JNDI 名稱快取資源,天然避免重載衝突,且惠及所有應用。WebSphere 等容器已內建此機制。此外,物件可在實例變數快取自身使用的 JNDI 參考。

結語

J2EE 1.3 引入的資源名稱重載機制,使帶快取的單例 Service Locator 成為錯誤溫床。結論明確:Service Locator 不應包含資源快取。保留模式封裝 JNDI 查找、以單例提供統一存取介面,但移除快取邏輯,確保正確性與可攜性。

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