什么是代理
我們大家都知道微商代理褐隆,簡(jiǎn)單地說(shuō)就是代替廠(chǎng)家賣(mài)商品侦副,廠(chǎng)家“委托”代理為其銷(xiāo)售商品侦锯。關(guān)于微商代理,首先我們從他們那里買(mǎi)東西時(shí)通常不知道背后的廠(chǎng)家究竟是誰(shuí)秦驯,也就是說(shuō)尺碰,“委托者”對(duì)我們來(lái)說(shuō)是不可見(jiàn)的;我們把微商代理和廠(chǎng)家進(jìn)一步抽象,前者可抽象為代理類(lèi)汇竭,后者可抽象為委托類(lèi)(被代理類(lèi))葱蝗。通過(guò)使用代理穴张,通常有兩個(gè)優(yōu)點(diǎn)细燎,并且能夠分別與我們提到的微商代理的兩個(gè)特點(diǎn)對(duì)應(yīng)起來(lái):
優(yōu)點(diǎn)一:可以隱藏委托類(lèi)的實(shí)現(xiàn);
優(yōu)點(diǎn)二:可以實(shí)現(xiàn)客戶(hù)與委托類(lèi)間的解耦,在不修改委托類(lèi)代碼的情況下能夠做一些額外的處理皂甘。
靜態(tài)代理
由程序員創(chuàng)建或工具生成代理類(lèi)的源碼玻驻,再編譯代理類(lèi)。所謂靜態(tài)也就是在程序運(yùn)行前就已經(jīng)存在代理類(lèi)的字節(jié)碼文件偿枕,代理類(lèi)和委托類(lèi)的關(guān)系在運(yùn)行前就確定了璧瞬。若代理類(lèi)在程序運(yùn)行前就已經(jīng)存在,那么這種代理方式被成為 靜態(tài)代理 渐夸,這種情況下的代理類(lèi)通常都是我們?cè)贘ava代碼中定義的嗤锉。 通常情況下, 靜態(tài)代理中的代理類(lèi)和委托類(lèi)會(huì)實(shí)現(xiàn)同一接口或是派生自相同的父類(lèi)墓塌。 下面我們用Vendor類(lèi)代表生產(chǎn)廠(chǎng)家瘟忱,Business類(lèi)代表微商代理,來(lái)介紹下靜態(tài)代理的簡(jiǎn)單實(shí)現(xiàn)苫幢,委托類(lèi)和代理類(lèi)都實(shí)現(xiàn)了Sell接口.:
//接口
public interface Sell {
void sell();
}
public class Business implements Sell{
public void sell() {
System.out.println("代理買(mǎi)東西");
}
}
public class Vendor implements Sell{
public void sell() {
System.out.println("廠(chǎng)家買(mǎi)東西");
}
}
public class Test {
public static void main(String[] args) {
Sell s=new Vendor();
s.sell();
}
}
測(cè)試結(jié)果:廠(chǎng)家買(mǎi)東西
靜態(tài)代理類(lèi)優(yōu)缺點(diǎn)
優(yōu)點(diǎn):業(yè)務(wù)類(lèi)只需要關(guān)注業(yè)務(wù)邏輯本身访诱,保證了業(yè)務(wù)類(lèi)的重用性。這是代理的共有優(yōu)點(diǎn)韩肝。
缺點(diǎn):
1)代理對(duì)象的一個(gè)接口只服務(wù)于一種類(lèi)型的對(duì)象触菜,如果要代理的方法很多,勢(shì)必要為每一種方法都進(jìn)行代理哀峻,靜態(tài)代理在程序規(guī)模稍大時(shí)就無(wú)法勝任了涡相。
2)如果接口增加一個(gè)方法哲泊,除了所有實(shí)現(xiàn)類(lèi)需要實(shí)現(xiàn)這個(gè)方法外,所有代理類(lèi)也需要實(shí)現(xiàn)此方法漾峡。增加了代碼維護(hù)的復(fù)雜度攻旦。
動(dòng)態(tài)代理
代理類(lèi)在程序運(yùn)行時(shí)創(chuàng)建的代理方式被成為 動(dòng)態(tài)代理。 也就是說(shuō)生逸,這種情況下牢屋,代理類(lèi)并不是在Java代碼中定義的,而是在運(yùn)行時(shí)根據(jù)我們?cè)贘ava代碼中的“指示”動(dòng)態(tài)生成的槽袄。相比于靜態(tài)代理烙无, 動(dòng)態(tài)代理的優(yōu)勢(shì)在于可以很方便的對(duì)代理類(lèi)的函數(shù)進(jìn)行統(tǒng)一的處理,而不用修改每個(gè)代理類(lèi)的函數(shù)遍尺。 這么說(shuō)比較抽象截酷,下面我們結(jié)合一個(gè)實(shí)例來(lái)介紹一下動(dòng)態(tài)代理的這個(gè)優(yōu)勢(shì)是怎么體現(xiàn)的
//代理商
public class Business implements InvocationHandler{
//指示
private Object obj;
// public void sell() {
// System.out.println("代理買(mǎi)東西");
//
// }
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
public Business(Object obj) {
super();
this.obj = obj;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
method.invoke(obj, args);
//System.out.println("代理買(mǎi)東西");
return obj;
}
}
測(cè)試
public class Test {
public static void main(String[] args) {
Business b=new Business(new Vendor());
Sell s=(Sell)Proxy.newProxyInstance(Vendor.class.getClassLoader(), Vendor.class.getInterfaces(), b);
s.sell();
}
}
測(cè)試結(jié)果:廠(chǎng)家買(mǎi)東西
動(dòng)態(tài)代理實(shí)現(xiàn)步驟
具體步驟是:
a. 實(shí)現(xiàn)InvocationHandler接口創(chuàng)建自己的調(diào)用處理器
b. 給Proxy類(lèi)提供ClassLoader和代理接口類(lèi)型數(shù)組創(chuàng)建動(dòng)態(tài)代理類(lèi)
c. 以調(diào)用處理器類(lèi)型為參數(shù),利用反射機(jī)制得到動(dòng)態(tài)代理類(lèi)的構(gòu)造函數(shù)
d. 以調(diào)用處理器對(duì)象為參數(shù)乾戏,利用動(dòng)態(tài)代理類(lèi)的構(gòu)造函數(shù)創(chuàng)建動(dòng)態(tài)代理類(lèi)對(duì)象
動(dòng)態(tài)代理的優(yōu)點(diǎn)
優(yōu)點(diǎn):
動(dòng)態(tài)代理與靜態(tài)代理相比較迂苛,最大的好處是接口中聲明的所有方法都被轉(zhuǎn)移到調(diào)用處理器一個(gè)集中的方法中處理(InvocationHandler.invoke)。這樣鼓择,在接口方法數(shù)量比較多的時(shí)候三幻,我們可以進(jìn)行靈活處理,而不需要像靜態(tài)代理那樣每一個(gè)方法進(jìn)行中轉(zhuǎn)呐能。
推介:
http://doushini.iteye.com/blog/1847913
http://www.jb51.net/article/95685.htm