1. 程式人生 > 實用技巧 >Proxy類實現java動態代理

Proxy類實現java動態代理


動態代理可以提供對另一個物件的訪問,同時隱藏實際物件的具體事實。代理一般會實現它所表示的實際物件的介面。
代理可以訪問實際物件,但是延遲實現實際物件的部分功能,實際物件實現系統的實際功能,
代理物件對客戶隱藏了實際物件。客戶不知道它是與代理打交道還是與實際物件打交道。

1.JDK代理使用的是反射機制實現aop的動態代理

2.JDK動態代理是通過方法呼叫,在呼叫目標方法前後增加程式碼來實現類行為改變

3.JDK動態代理機制是委託機制,具體說動態實現介面類,在動態生成的實現類裡面委託hanlder去呼叫原始實現類方法,

目前Java開發包中包含了對動態代理的支援,但是其實現只支援對介面的的實現。 其實現主要通過java.lang.reflect.Proxy類
和java.lang.reflect.InvocationHandler介面。

Proxy類主要用來獲取動態代理物件,InvocationHandler介面用來約束呼叫者實現

通過動態代理實現在方法呼叫前後向控制檯輸出兩句字串:

   1.定義一個HelloWorld介面

  package com..test;
  
   /**
   * 定義一個HelloWorld介面
   * 
   */
   public interface HelloWorld {
     public void sayHelloWorld();
 }

2.類HelloWorldImpl是HelloWorld介面的實現

  package com..test;
  
   /**
* 類HelloWorldImpl是HelloWorld介面的實現 * * */ public class HelloWorldImpl implements HelloWorld{ public void sayHelloWorld() { System.out.println("HelloWorld!"); } }

3.HelloWorldHandler是 InvocationHandler介面實現



package com..test;
  
   import java.lang.reflect.InvocationHandler;
   
import java.lang.reflect.Method; /** * 實現在方法呼叫前後向控制檯輸出兩句字串 * */ public class HelloWorldHandler implements InvocationHandler{ //要代理的原始物件 private Object obj; public HelloWorldHandler(Object obj) { super(); this.obj = obj; } /** * 在代理例項上處理方法呼叫並返回結果 * * @param proxy 代理類 * @param method 被代理的方法 * @param args 該方法的引數陣列 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; //呼叫之前 doBefore(); //呼叫原始物件的方法 result=method.invoke(obj, args); //呼叫之後 doAfter(); return result; } private void doBefore(){ System.out.println("before method invoke"); } private void doAfter(){ System.out.println("after method invoke"); } }

4.測試
package com..test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;


public class HelloWorldTest {

    public static void main(String[] args) {
        HelloWorld helloWorld=new HelloWorldImpl();
        InvocationHandler handler=new HelloWorldHandler(helloWorld);
        
        //建立動態代理物件
        HelloWorld proxy=(HelloWorld)Proxy.newProxyInstance(
                helloWorld.getClass().getClassLoader(), 
                helloWorld.getClass().getInterfaces(), 
                handler);
        proxy.sayHelloWorld();
    }
}