程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java理論與實踐: 用動態代理進行修飾

Java理論與實踐: 用動態代理進行修飾

編輯:關於JAVA

  動態代理為實現許多常見設計模式(包括 Facade、Bridge、Interceptor、Decorator、Proxy(包括遠程和虛擬代理)和 Adapter 模式)提供了替代的動態機制。雖然這些模式不使用動態代理,只用普通的類就能夠實現,但是在許多情況下,動態代理方式更方便、更緊湊,可以清除許多手寫或生成的類。
  
  Proxy 模式
  
  Proxy 模式中要創建“stub”或“surrogate”對象,它們的目的是接受請求並把請求轉發到實際執行工作的其他對象。遠程方法調用(RMI)利用 Proxy 模式,使得在其他 JVM 中執行的對象就像本地對象一樣;企業 JavaBeans (EJB)利用 Proxy 模式添加遠程調用、安全性和事務分界;而 JAX-RPC Web 服務則用 Proxy 模式讓遠程服務表現得像本地對象一樣。在每一種情況中,潛在的遠程對象的行為是由接口定義的,而接口本質上接受多種實現。調用者(在大多數情況下)不能區分出它們只是持有一個對 stub 而不是實際對象的引用,因為二者實現了相同的接口;stub 的工作是查找實際的對象、封送參數、把參數發送給實際對象、解除封送返回值、把返回值返回給調用者。代理可以用來提供遠程控制(就像在 RMI、EJB 和 JAX-RPC 中那樣),用安全性策略包裝對象(EJB)、為昂貴的對象(EJB 實體 Bean)提供惰性裝入,或者添加檢測工具(例如日志記錄)。
  
  在 5.0 以前的 JDK 中,RMI stub(以及它對等的 skeleton)是在編譯時由 RMI 編譯器(rmic)生成的類,RMI 編譯器是 JDK 工具集的一部分。對於每個遠程接口,都會生成一個 stub(代理)類,它代表遠程對象,還生成一個 skeleton 對象,它在遠程 JVM 中做與 stub 相反的工作 —— 解除封送參數並調用實際的對象。類似地,用於 Web 服務的 JAX-RPC 工具也為遠程 Web 服務生成代理類,從而使遠程 Web 服務看起來就像本地對象一樣。
  
  不管 stub 類是以源代碼還是以字節碼生成的,代碼生成仍然會向編譯過程添加一些額外步驟,而且因為命名相似的類的泛濫,會帶來意義模糊的可能性。另一方面,動態代理機制支持在編譯時沒有生成 stub 類的情況下,在運行時創建代理對象。在 JDK 5.0 及以後版本中,RMI 工具使用動態代理代替了生成的 stub,結果 RMI 變得更容易使用。許多 J2EE 容器也使用動態代理來實現 EJB。EJB 技術嚴重地依靠使用攔截(interception)來實現安全性和事務分界;動態代理為接口上調用的所有方法提供了集中的控制流程路徑。
  
  動態代理機制
  
  動態代理機制的核心是 InvocationHandler 接口,如清單 1 所示。調用句柄的工作是代表動態代理實際執行所請求的方法調用。傳遞給調用句柄一個 Method 對象(從 Java.lang.reflect 包),參數列表則傳遞給方法;在最簡單的情況下,可能僅僅是調用反射性的方法 Method.invoke() 並返回結果。
  
  清單 1. InvocationHandler 接口
  
  public interface InvocationHandler {
  Object invoke(Object proxy, Method method, Object[] args)
  throws Throwable;
  }
  
  每個代理都有一個與之關聯的調用句柄,只要代理的方法被調用時就會調用該句柄。根據通用的設計原則:接口定義類型、類定義實現,代理對象可以實現一個或多個接口,但是不能實現類。因為代理類沒有可以訪問的名稱,它們不能有構造函數,所以它們必須由工

[1] [2] [3] [4] [5] [6] 下一頁

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved