靜態(tài)代理
代理模式可以在不修改被代理對象的基礎上,通過擴展代理類花嘶,進行一些功能的附加與增強琳彩。值得注意的是誊酌,代理類和被代理類應該共同實現(xiàn)一個接口部凑,或者是共同繼承某個類。
public interface Movie {
void play();
}
真正的實現(xiàn)類
public class RealMovie implements Movie {
@Override
public void play() {
// TODO Auto-generated method stub
System.out.println("您正在觀看電影 《肖申克的救贖》");
}
}
靜態(tài)代理 對movie進行代理
public class Cinema implements Movie {
RealMovie movie;
public Cinema(RealMovie movie) {
super();
this.movie = movie;
}
@Override
public void play() {
guanggao(true);
movie.play();
guanggao(false);
}
public void guanggao(boolean isStart){
if ( isStart ) {
System.out.println("電影馬上開始了碧浊,爆米花涂邀、可樂、口香糖9.8折箱锐,快來買氨让恪!");
} else {
System.out.println("電影馬上結束了驹止,爆米花浩聋、可樂、口香糖9.8折臊恋,買回家吃吧衣洁!");
}
}
}
public class ProxyTest {
public static void main(String[] args) {
RealMovie realmovie = new RealMovie();
Movie movie = new Cinema(realmovie);
movie.play();
}
}
動態(tài)代理
上面代碼中 Cinema 類是代理,我們需要手動編寫代碼讓 Cinema 實現(xiàn) Movie 接口抖仅,而在動態(tài)代理中坊夫,我們可以讓程序在運行的時候自動在內存中創(chuàng)建一個實現(xiàn) Movie 接口的代理,而不需要去定義 Cinema 這個類岸售。這就是它被稱為動態(tài)的原因践樱。
假設有一個大商場,商場有很多的柜臺凸丸,有一個柜臺賣茅臺酒
//賣酒的許可證
public interface SellWine {
void mainJiu();
}
public class MaotaiJiu implements SellWine {
@Override
public void mainJiu() {
// TODO Auto-generated method stub
System.out.println("我賣得是茅臺酒拷邢。");
}
}
public class GuitaiA implements InvocationHandler {
private Object pingpai;
public GuitaiA(Object pingpai) {
this.pingpai = pingpai;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
System.out.println("銷售開始 柜臺是: "+this.getClass().getSimpleName());
method.invoke(pingpai, args);
System.out.println("銷售結束");
return null;
}
}
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
MaotaiJiu maotaijiu = new MaotaiJiu();
InvocationHandler jingxiao1 = new GuitaiA(maotaijiu);
SellWine dynamicProxy = (SellWine) Proxy.newProxyInstance(MaotaiJiu.class.getClassLoader(),
MaotaiJiu.class.getInterfaces(), jingxiao1);
dynamicProxy.mainJiu();
}
}
方法解析
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
loader 自然是類加載器,interfaces 代碼要用來代理的接口屎慢,h 一個 InvocationHandler 對象
InvocationHandler
InvocationHandler 是一個接口瞭稼,官方文檔解釋說,每個代理的實例都有一個與之關聯(lián)的 InvocationHandler 實現(xiàn)類腻惠,如果代理的方法被調用环肘,那么代理便會通知和轉發(fā)給內部的 InvocationHandler 實現(xiàn)類,由它決定處理集灌。
因為悔雹,Proxy 動態(tài)產生的代理會調用 InvocationHandler 實現(xiàn)類,所以 InvocationHandler 是實際執(zhí)行者欣喧。
紅框中 $Proxy0 就是通過 Proxy 動態(tài)生成的腌零。
$Proxy0 實現(xiàn)了要代理的接口。
$Proxy0 通過調用 InvocationHandler 來執(zhí)行任務唆阿。
上一篇代理模式回顧:
http://www.reibang.com/p/ed281dcf9fa7
參考文章:
https://blog.csdn.net/briblue/article/details/73928350