代理是一種常用設計模式,其目的就是爲其他對象提供一個代理以控制對某個對象的訪問。代理類負責爲委託類預處理消息,過濾消息並轉發消息,以及進行消息被委託類執行後的後續處理。
靜態代理的一個代理只能代理一種類型,而且是在編譯器就已經確定被代理的對象。而動態代理是在運行時,通過反射機制實現動態代理,而且能過代理各種類型的對象。
//靜態代理
由程序員創建或工具生成代理類的源碼,再編譯代理類。所謂靜態也就是在程序運行前就已經存在代理類的字節碼文件,代理類和委託類的關係在運行前就確定了。
public class Proxy implements Subject{
private RealSubject realSubject;
public Proxy(RealSubject realSubject){
this.realSubject = realSubject;
}
@Override
public void giveGift(){
realSubject.giveGift();
}
}
靜態代理類的缺點:當如果加一個方法,所有的實現類和代理類裏都需要做個實現。這就增加了代碼的複雜度。動態代理就可以避免這個缺點。
//動態代理
動態代理類的源碼是在程序運行期間由JVM根據反射等機制動態的生成,所以不存在代理類的字節碼文件。代理類和委託類的關係是在程序運行時確定。
動態代理在Java中要想實現動態代理機制,需要java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy類的支持。
public class DynamicProxy implements InvocationHandler{
private Object obj;//委託類
public DynamicProxy(Object obj){
this.obj = obj;
}
@Override
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
-
System.out.println("obj : " + obj.getClass().getName());
-
System.out.println("proxy : " + proxy.getClass().getName());
-
System.out.println("method : " + method.getName());
- System.out.println("args : " + args);
}
Object result = method.invoke(this.obj.args);
return result;
}
public class Client{
public static void main(String args[]){
Subject realSubject = new RealSubject();
ClassLoader loader = realSubject.getClass().getClassLoader();
Class<?>[] interfaces =realSubject.getClass().getInterfaces();
InvocationHandler handler new = DynamicProxy(realSubject);
Subject dynamicProxy = (Subject)Proxy.newProxyInstance(loader,interfaces,handler);
dynaminProxy.giveGift();
}
}
代理模式可以通過聚合和繼承兩種方式實現。
動態代理實現:
1. 創建一個實現InvocationHandler接口的類,它必須實現invoke()方法
2. 創建被代理的類及接口
3. 調用Proxy的靜態方法,創建一個代理類
4. 通過代理調用方法