什么是代理
我們大家都知道微商代理,簡單地說就是代替廠家賣商品,廠家“委托”代理為其銷售商品。關(guān)于微商代理,首先我們從他們那里買東西時通常不知道背后的廠家究竟是誰,也就是說,“委托者”對我們來說是不可見的;我們把微商代理和廠家進一步抽象,前者可抽象為代理類,后者可抽象為委托類(被代理類)。通過使用代理,通常有兩個優(yōu)點,并且能夠分別與我們提到的微商代理的兩個特點對應(yīng)起來:
優(yōu)點一:可以隱藏委托類的實現(xiàn);
優(yōu)點二:可以實現(xiàn)客戶與委托類間的解耦,在不修改委托類代碼的情況下能夠做一些額外的處理。
靜態(tài)代理
由程序員創(chuàng)建或工具生成代理類的源碼,再編譯代理類。所謂靜態(tài)也就是在程序運行前就已經(jīng)存在代理類的字節(jié)碼文件,代理類和委托類的關(guān)系在運行前就確定了。若代理類在程序運行前就已經(jīng)存在,那么這種代理方式被成為 靜態(tài)代理 ,這種情況下的代理類通常都是我們在Java代碼中定義的。 通常情況下, 靜態(tài)代理中的代理類和委托類會實現(xiàn)同一接口或是派生自相同的父類。 下面我們用Vendor類代表生產(chǎn)廠家,Business類代表微商代理,來介紹下靜態(tài)代理的簡單實現(xiàn),委托類和代理類都實現(xiàn)了Sell接口.:
//接口
public interface Sell {
void sell();
}
public class Business implements Sell{
public void sell() {
System.out.println("代理買東西");
}
}
public class Vendor implements Sell{
public void sell() {
System.out.println("廠家買東西");
}
}
public class Test {
public static void main(String[] args) {
Sell s=new Vendor();
s.sell();
}
}
測試結(jié)果:廠家買東西
靜態(tài)代理類優(yōu)缺點
優(yōu)點:業(yè)務(wù)類只需要關(guān)注業(yè)務(wù)邏輯本身,保證了業(yè)務(wù)類的重用性。這是代理的共有優(yōu)點。
缺點:
1)代理對象的一個接口只服務(wù)于一種類型的對象,如果要代理的方法很多,勢必要為每一種方法都進行代理,靜態(tài)代理在程序規(guī)模稍大時就無法勝任了。
2)如果接口增加一個方法,除了所有實現(xiàn)類需要實現(xiàn)這個方法外,所有代理類也需要實現(xiàn)此方法。增加了代碼維護的復(fù)雜度。
動態(tài)代理
代理類在程序運行時創(chuàng)建的代理方式被成為 動態(tài)代理。 也就是說,這種情況下,代理類并不是在Java代碼中定義的,而是在運行時根據(jù)我們在Java代碼中的“指示”動態(tài)生成的。相比于靜態(tài)代理, 動態(tài)代理的優(yōu)勢在于可以很方便的對代理類的函數(shù)進行統(tǒng)一的處理,而不用修改每個代理類的函數(shù)。 這么說比較抽象,下面我們結(jié)合一個實例來介紹一下動態(tài)代理的這個優(yōu)勢是怎么體現(xiàn)的
//代理商
public class Business implements InvocationHandler{
//指示
private Object obj;
// public void sell() {
// System.out.println("代理買東西");
//
// }
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("代理買東西");
return obj;
}
}
測試
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();
}
}
測試結(jié)果:廠家買東西
動態(tài)代理實現(xiàn)步驟
具體步驟是:
a. 實現(xiàn)InvocationHandler接口創(chuàng)建自己的調(diào)用處理器
b. 給Proxy類提供ClassLoader和代理接口類型數(shù)組創(chuàng)建動態(tài)代理類
c. 以調(diào)用處理器類型為參數(shù),利用反射機制得到動態(tài)代理類的構(gòu)造函數(shù)
d. 以調(diào)用處理器對象為參數(shù),利用動態(tài)代理類的構(gòu)造函數(shù)創(chuàng)建動態(tài)代理類對象
動態(tài)代理的優(yōu)點
優(yōu)點:
動態(tài)代理與靜態(tài)代理相比較,最大的好處是接口中聲明的所有方法都被轉(zhuǎn)移到調(diào)用處理器一個集中的方法中處理(InvocationHandler.invoke)。這樣,在接口方法數(shù)量比較多的時候,我們可以進行靈活處理,而不需要像靜態(tài)代理那樣每一個方法進行中轉(zhuǎn)。
推介:
http://doushini.iteye.com/blog/1847913
http://www.jb51.net/article/95685.htm