動態代理

利用代理可以在運行時創建一個實現了一組給定接口的新類。代理類具有下列方法:

  • 指定接口所需要的全部方法。
  • Object 類中的全部方法, 例如, toString、 equals 等。

實現代理只需要使用Proxy的newProxyInstance方法,該方法需要接收三個參數,完整的寫法是:

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )
  • ClassLoader loader,一個類加載器,null表示使用默認的類加載器。
  • Class<?>[] interfaces,一個 Class 對象數組, 每個元素都是需要實現的接口。
  • InvocationHandler h,一個調用處理器

InvocationHandler這個接口的唯一一個方法 invoke 方法:

Object invoke(Object proxy, Method method, Object[] args) throws Throwable

舉例:
使用代理和調用處理器跟蹤方法調用,定義了一個 TraceHander 包裝器類存儲包裝的對象。其中的 invoke 方法打印出被調用方法的名字和參數,隨後用包裝好的對象作爲隱式參數調用這個方法。

class TraceHandler implements InvocationHandler
{
   private Object target;
   
   public TraceHandler(Object t)
   {
      target = t;
   }

   public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
   {
      // print method name and parameters
		......
      // invoke actual method
      return m.invoke(target, args);
   }
}

下面說明如何構造用於跟蹤方法調用的代理對象。

Object value=......
// construct wrapper
InvocationHandler handler = new TraceHandler(value);
// construct proxy for one or more interfaces
Class[] interfaces = new Class[] {Comparable.class};
Object proxy = Proxy.newProxylnstance(null , interfaces , handler);

現在,用 proxy 調用compareTo方法, 這個方法的名字和參數就會打印出來,之後再用被代理的對象 value 調用它。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章