代理模式:
某一個(gè)對象提供一個(gè)代理對象居砖,并由代理對象控制對原對象的引用。
目的:
1驴娃、通過引入代理對象的方式來間接訪問目標(biāo)對象奏候,防止直接訪問目標(biāo)對象給系統(tǒng)帶來的不必要復(fù)雜性;
2唇敞、通過代理對象對訪問進(jìn)行控制蔗草;
抽象角色:指代理角色和真實(shí)角色對外提供的公共方法,一般為一個(gè)接口疆柔。
真實(shí)角色:需要實(shí)現(xiàn)抽象角色接口咒精,定義了真實(shí)角色所要實(shí)現(xiàn)的業(yè)務(wù)邏輯,以便供代理角色調(diào)用旷档。也就是真正的業(yè)務(wù)邏輯在此狠轻。
代理角色:需要實(shí)現(xiàn)抽象角色接口,是真實(shí)角色的代理彬犯,通過真實(shí)角色的業(yè)務(wù)邏輯方法來實(shí)現(xiàn)抽象方法,并可以附加自己的操作查吊。將統(tǒng)一的流程控制都放到代理角色中處理谐区。
靜態(tài)代理:
靜態(tài)代理在使用時(shí),需要定義接口或者父類逻卖,被代理對象與代理對象一起實(shí)現(xiàn) 相同的接口或者是 繼承相同 父類宋列。一般來說,被代理對象和代理對象是一對一的關(guān)系评也,當(dāng)然一個(gè)代理對象對應(yīng)多個(gè)被代理對象也是可以的炼杖。
靜態(tài)代理灭返,一對一則會(huì)出現(xiàn)時(shí)靜態(tài)代理對象量多、代碼量大坤邪,從而導(dǎo)致代碼復(fù)雜熙含,可維護(hù)性差的問題,一對多則代理對象會(huì)出現(xiàn)擴(kuò)展能力差的問題艇纺。
動(dòng)態(tài)代理:
動(dòng)態(tài)代理是指客戶通過代理類來調(diào)用其它對象的方法怎静,并且是在程序運(yùn)行時(shí)根據(jù)需要?jiǎng)討B(tài)創(chuàng)建目標(biāo)類的代理對象。即不直接找到被代理對象黔衡,而是找被代理對象的經(jīng)紀(jì)人蚓聘,從而由經(jīng)紀(jì)人在找到被代理對象。代理對象較多的情況下盟劫,更適合使用動(dòng)態(tài)代理夜牡,降低代碼量和耦合度。
動(dòng)態(tài)代理實(shí)現(xiàn)如下:
//抽象角色
interface Api {
void test(String a);
}
//真實(shí)角色
static class ApiImpl implements Api {
@Override
public void test(String a) {
System.out.println("api 實(shí)現(xiàn)內(nèi)容:" + a);
}
}
public static void main(final String[] args) throws Exception {
//真實(shí)角色實(shí)例
final Api api = new ApiImpl();
api.test("直接測試");
/**
* Proxy.newProxyInstance 創(chuàng)建了一個(gè)Class侣签,僅在內(nèi)存中生成
* Object o 為代理對象,即Proxy.newProxyInstance 的返回值
* Method method 為調(diào)用的方法
* Object[] objects 為方法傳入的參數(shù)
* InvocationHandler 是監(jiān)聽回調(diào)塘装,在代理對象上執(zhí)行方法,都會(huì)由這個(gè)監(jiān)聽回調(diào)出來
*/
Object obj = Proxy.newProxyInstance(Api.class.getClassLoader(),
new Class[]{Api.class}, //JDK實(shí)現(xiàn)只能 代理接口
new InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
for (Object obj : objects) {
System.out.println("傳參 " + obj);
}
//執(zhí)行真實(shí)對象方法
return method.invoke(api, objects);
}
}
);
//真實(shí)角色實(shí)例
Api api1 = (Api) obj;
api1.test("動(dòng)態(tài)代理");
}
得到結(jié)果
api 實(shí)現(xiàn)內(nèi)容:直接測試
動(dòng)態(tài)代理測試
api 實(shí)現(xiàn)內(nèi)容:動(dòng)態(tài)代理
靜態(tài)/動(dòng)態(tài) 代理區(qū)別如下: