最近空閒時間在研究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;
}
}
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