代理模式也被稱爲委託模式,它是結構型設計模式的一種。在現實生活中咱們用到相似代理模式的場景有不少,好比代理上網、打官司等。設計模式
爲其餘對象提供一種代理以控制對這個對象的訪問。安全
Server
部分的實現隱藏。我多年沒有回哈爾濱了,很想念哈爾濱的秋林紅腸味道。可是本人由於工做一直很忙抽不開身,不可以親自回哈爾濱購買,因而就拜託在哈爾濱的朋友幫我購買秋林紅腸。bash
buy
public interface IShop {
void buy();
}
複製代碼
Giants
就是我,實現了 IShop
接口提供的 buy
方法。public class Giants implements IShop {
@Override
public void buy() {
System.out.println("購買");
}
}
複製代碼
IShop
接口,而且要持有被代理者,在 buy
方法中調用了被代理者的 buy
方法。public class Purchasing implements IShop {
private IShop mShop;
public Purchasing(IShop shop) {
this.mShop = shop;
}
@Override
public void buy() {
mShop.buy();
}
}
複製代碼
public class Client {
public static void main(String[] args) {
IShop giants = new Giants();
IShop purchasing = new Purchasing(giants);
purchasing.buy();
}
}
複製代碼
上面的例子是一個靜態的代理,在代碼運行前已經存在了代理類的
class
編譯文件;而動態代理則是在帶來運行時經過反射來動態地生成代理類的對象,並肯定到底代理誰。咱們在編碼階段無需知道代理誰,代理誰將會在代碼運行時覺定。ide
/**
* 實現Java提供的動態代理接口 InvocationHandler ,實現該接口須要重寫 invoke 方法
*/
public class DynamicPurchasing implements InvocationHandler {
private Object obj;
public DynamicPurchasing(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(obj, args);
if(method.getName().equals("buy")){
System.out.println("Giants在買買買");
}
return result;
}
}
複製代碼
Proxy.newProxyInstance
來生成動態代理類,調用 purchasing
的 buy
方法會調用 mDynamicPurchasing
的 invoke
方法。public class Client {
public static void main(String[] args) {
//建立 Giants
IShop giants = new Giants();
//建立動態代理
DynamicPurchasing mDynamicPurchasing = new DynamicPurchasing(giants);
//建立 giants 的 ClassLoader
ClassLoader loader = giants.getClass().getClassLoader();
//動態建立代理類
IShop purchasing = (IShop) Proxy.newProxyInstance(loader, new Class[] {IShop.class}, mDynamicPurchasing);
purchasing.buy();
}
}
複製代碼