簡單易懂的JDK動態代理

jdk動態代理是java.lang.reflect.*包提供的方式,他必須藉助一個藉口才能產生代理對象,所以先定義接口:    
/**
 * JDK動態代理必須藉助藉口才能產生代理對象
 * */
public interface HelloWorld {
    public void sayHello();
}
然後提供該接口的實現類
public class HelloWorldImpl implements HelloWorld {
    @Override
    public void sayHello() {
        System.out.println("Hello");
    }
}
   這是最簡單的接口和實現類的關係,此時可以動態代理了,首先要建立代理對象和真實對象之間的關係,然後實現代理邏輯,so
   在JDK動態代理中,要實現代理邏輯類必須去實現java.lang.reflect.InvocationHandler接口,它裏面定義了一個invoke方法,並提供了接口數組用於下掛代理對象,代碼如下:
public class JDKProxyExample implements InvocationHandler {

    private Object target=null; //真是的對象

    /**
     * 建立代理對象和真實對象的代理關係
     * @param target 真實對象
     * @return 代理對象
     * */
    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    /**
     * 代理方法邏輯
     * @param proxy 代理對象
     * @param method 當前調度的方法
     * @param args 當前方法的參數
     * @return 代理結果返回
     * @throws Throwable 異常
     * */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("進入代理邏輯方法");
        System.out.println("在調度真實對象之前的服務");
        Object obj = method.invoke(target, args); //相當於調用sayHello方法
        System.out.println("在調度真實對象之後的服務");
        return obj;
    }

}

 1. 建立代理對象和真實對象之間的關係,這裏使用bind方法完成的,方法裏面首先用類的屬性target對象保存了真實對象,然後通過如下代碼生成代理對象:
     Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
   newProxyInstance方法的三個參數:
   ①.第一個數類加載器,採用target本身的類加載器;
   ②.第二個是把生成的動態代理對象下掛在哪些接口(這裏是Class類型的數組),HelloWorldImpl對象的接口顯然就是HelloWorld,代理對象可以這樣聲明:Hello proxy = xxx;
   ③.第三個是定義實現方法邏輯的代理類,this表示當前對象,它必須實現InvocationHandler接口的invoke方法,他就是代理邏輯方法的實現方法。

 2. 實現代理邏輯方法。invoke方法刻可以實現代理邏輯,invoke方法的三個參數含義如下:
   ①.proxy:代理對象,就是bind方法生成的對象
   ②.method:當前調度的方法,
   ③.args,調度方法的參數
    當我們使用代理對象調度方法之後,它就會進入到invokeff裏面。
    Object obj = method.invoke(target, args);
    這行代碼相當於調度真實對象的方法,只是通過反射實現而已
測試JDK動態代理,代碼如下:
    public static void main(String[] args) {
        JDKProxyExample jdk = new JDKProxyExample();

        //綁定關係,因爲掛在接口HelloWorld下,所以聲明代理對象HelloWord proxy
        HelloWorld proxy = (HelloWorld)jdk.bind(new HelloWorldImpl());

        //此時HelloWorld對象已經是一個代理對象,它會進入代理的邏輯方法invoke裏面
        proxy.sayHello();
    }
}

運行結果:
運行結果

上述代碼源碼下載:
源碼下載,有問題請留言!

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