Java的代理—JDK Proxy

最近空閒時間在研究dubbo,裏面用到了代理,正好這塊以前不怎麼了解,現在學習並記錄下來。

參考:Java核心技術 卷I 基礎知識(原書第9版) 6.5 代理


JDK代理是Java 1.3新增的特性,主要用於以下一些場景:

  • 路由對遠程服務器的方法調用。
  • 在程序運行期間,將用戶接口事件與動作關聯起來。
  • 爲調試,跟蹤方法調用。

JDK代理的實現原理是通過反射機制實例化被代理類及調用被代理的方法,在這個過程中可以做一些自定義的操作。

要被代理的類必須實現一個接口,沒有實現接口的話,就無法使用JDK代理,不過CGLib代理不受此限制,並且由於底層是通過ASM字節碼生成新的類,效率更高一些。


下面通過一個例子演示一下JDK代理。

首先寫一個接口:

public interface Animal {
    void sayHello();
}

接着是實現類:

public class Dog implements Animal {
    private String name;

    public Dog(String name) {
        this.name = name;
    }

    public void sayHello() {
        System.out.println("Hello, my name is " + name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
接下來實現一種很簡單代理類,該代理類在方法執行前打印了下被代理類的名字,在方法執行後打印了一段話:
public class MethodHandler implements InvocationHandler {
    private Object target;

    public MethodHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(target.getClass().getName());
        Object result = method.invoke(target, args);
        System.out.println("proxy end");

        return result;
    }
}
最後我們將Dog類進行代理,並測試:
public class Main {
    private static Animal findADog(String name) {
        Animal animal = new Dog(name);
        return (Animal) Proxy.newProxyInstance(animal.getClass().getClassLoader(), animal.getClass().getInterfaces(), new MethodHandler(animal));
    }

    public static void main(String[] args) {
        findADog("Teddy").sayHello();
    }
}
運行結果如下:
com.company.Dog
Hello, my name is Teddy
proxy end

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