asing1elife's blog
阿新 • • 發佈:2018-12-14
通過使用代理可以隱藏委託類的實現,並且實現客戶與委託類之間的解耦,在不修改委託類的前提下為客戶做一些額外處理
更多精彩
型別
- 靜態代理 - Java 代理之靜態代理
- 雖然具備代理的兩個優點
- 但侷限在於執行前必須編寫好代理類
- 動態代理
- 代理類在程式執行時才被建立
- 其優勢在於可以對多個代理類進行統一處理,而不用修改每個代理類的實現
定義 InvocationHandler 介面,充當呼叫處理器
- java.lang.reflect.InvocationHandler 是 Java 自帶的呼叫處理器
- 為處於代理類和委託類之間的中間類提供實現介面
- 代理類作為引數 proxy 傳入
- 引數 method 標識具體呼叫代理類的哪個方法
- 引數 args 是這個代理類方法的引數
public interface InvocationHandler {
Object invoke(Object proxy, Method method, Object[] args);
}
定義委託類,使用動態代理,委託類必須實現某個介面
public class Sell {
void sell();
void ad();
}
public class Vendor implements Sell {
public void sell() {
System.out.println ("In sell method");
}
public void ad() {
System.out.println("In ad method");
}
}
定義中介類,其必須實現 InvocationHandler 介面
- 該類持有一個委託類的引用
- 中介類和委託類構成靜態代理,中介類充當代理類,委託類依舊是委託類
- 中介類和代理類構成靜態代理,中介類充當委託類,代理類依舊是代理類
- 所以實際上動態代理是由兩組靜態代理組成
public class DynamicProxy implements InvocationHandler {
private Object object;
public DynamicProxy(Object object) {
this.object = object;
}
public void invoke(Object proxy, Mehtod method, Object[] args) {
System.out.println("-- before --");
Object result = method.invoke(object, args);
System.out.println("-- after --");
return result;
}
}
動態生成代理類
- 通過呼叫 Proxy.newProxyInstance() 獲取代理類例項,其實現指定介面並將方法滴啊用分發到指定的呼叫處理器
- 該方法的宣告
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
- 引數 loader 是定義了代理類的 ClassLoader
- 引數 interfaces 是代理類實現的介面列表
- 引數 h 是調動處理器
public class MainTest {
public static void main(String[] args) {
DynamicProxy dynamicProxy = new DynamicProxy(new Vendor());
Sell sell = (Sell) Proxy.newProxyInstance(Sell.class.getClassLoader(), new Class[]{Sell.class}, dynamicProxy);
sell.sell();
sell.ad();
}
}