一瓤狐、什么是代理模式?
? ? 定義: 為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)弯囊,重點(diǎn)在控制以及擴(kuò)展已有類(lèi)的功能
? ?通俗理解:? 就是一個(gè)中介潘明,通過(guò)該對(duì)象來(lái)訪問(wèn)另外一個(gè)對(duì)象
? ? 編程思想:?不要隨意去修改別人已經(jīng)寫(xiě)好的代碼或者方法,如果需改修改,可以通過(guò)代理的方式來(lái)擴(kuò)展? ? ? ? ? ? ? ? ? ? ? ?該方法
? ? ?案例理解:? 假設(shè)我們想邀請(qǐng)一位明星,那么并不是直接連接明星,而是聯(lián)系明星的經(jīng)紀(jì)人,來(lái)達(dá)到同樣的目的.明星就是一個(gè)目標(biāo)對(duì)象,他只要負(fù)責(zé)活動(dòng)中的節(jié)目,而其他瑣碎的事情就交給他的代理人(經(jīng)紀(jì)人)來(lái)解決蛋欣。
? ?代理模式理解重點(diǎn):代理對(duì)象與目標(biāo)對(duì)象.代理對(duì)象是對(duì)目標(biāo)對(duì)象的擴(kuò)展,并會(huì)調(diào)用目標(biāo)對(duì)象
二寡夹、代理模式種類(lèi)?
? ??代理模式分為 靜態(tài)代理模式处面,動(dòng)態(tài)代理模式, cglib代理,以下分別說(shuō)明這三種代理模式菩掏。
三魂角、靜態(tài)代理模式?
? ? ?特點(diǎn): 需要定義接口或者父類(lèi),被代理對(duì)象與代理對(duì)象一起實(shí)現(xiàn)相同的接口或者是繼承相同父類(lèi).
? ? ?角色?
? ? ?????目標(biāo)接口: 定義需要代理的對(duì)象接口
? ? ?????目標(biāo)對(duì)象: 定義需要代理的對(duì)象智绸,實(shí)現(xiàn)目標(biāo)接口
? ? ?????代理對(duì)象: 定義代理對(duì)象野揪,實(shí)現(xiàn)目標(biāo)接口,持有目標(biāo)對(duì)象引用
? ? ?分析??
? ? ? ? ? ? 優(yōu)點(diǎn):? ?可以做到在不修改目標(biāo)對(duì)象的功能前提下, 使用代理對(duì)象實(shí)現(xiàn)對(duì)目標(biāo)功能擴(kuò)展.
? ? ? ? ? ? 缺點(diǎn):? 因?yàn)榇韺?duì)象需要與目標(biāo)對(duì)象實(shí)現(xiàn)一樣的接口,所以會(huì)有很多代理類(lèi),類(lèi)太多.同時(shí)如果對(duì)目標(biāo)對(duì)象執(zhí)行方法前后的操作都一樣瞧栗,每個(gè)方法中存在前后執(zhí)行代碼的冗余代碼斯稳。一旦接口增 加方法,目標(biāo)對(duì)象與代理對(duì)象都要維護(hù).
? ? 如何解決靜態(tài)代理中的缺點(diǎn)呢?
? ? ? ? ? 答案是可以使用動(dòng)態(tài)代理方式
四、動(dòng)態(tài)代理模式迹恐???
由來(lái): 解決使用靜態(tài)代理造成代理類(lèi)太多挣惰,當(dāng)接口修改目標(biāo)與代理對(duì)象都要維護(hù)。
特點(diǎn):? 1.代理對(duì)象,不需要實(shí)現(xiàn)接口
? ? ? ? ? 2.代理對(duì)象的生成,是利用JDK的API, 動(dòng)態(tài)的在內(nèi)存中構(gòu)建代理對(duì)象(需要我們指定創(chuàng)建代理對(duì)象/
? ? ? ? ? ? ?目標(biāo)對(duì)象實(shí)現(xiàn)的接口的類(lèi)型)
? ? ? ? ? 3. 動(dòng)態(tài)代理也叫做:JDK代理,接口代理
? ? ? ? ? 4.?代理對(duì)象不需要實(shí)現(xiàn)接口,但是目標(biāo)對(duì)象一定要實(shí)現(xiàn)接口,否則不能用動(dòng)態(tài)代理
使用:?JDK中生成代理對(duì)象的API
代理類(lèi)所在包:java.lang.reflect.Proxy
JDK實(shí)現(xiàn)代理只需要使用newProxyInstance方法,但是該方法需要接收三個(gè)參數(shù),完整的寫(xiě)法是:
static Object newProxyInstance(ClassLoader loader, Class[] interfaces,InvocationHandler h )
注意該方法是在Proxy類(lèi)中是靜態(tài)方法,且接收的三個(gè)參數(shù)依次為:
ClassLoader loader,:指定當(dāng)前目標(biāo)對(duì)象使用類(lèi)加載器,獲取加載器的方法是固定的
Class[] interfaces,:目標(biāo)對(duì)象實(shí)現(xiàn)的接口的類(lèi)型,使用泛型方式確認(rèn)類(lèi)型
InvocationHandler h:事件處理,執(zhí)行目標(biāo)對(duì)象的方法時(shí),會(huì)觸發(fā)事件處理器的方法,會(huì)把當(dāng)前執(zhí)行目標(biāo)對(duì)象的方法作為參數(shù)傳入
五系草、Cglib代理
? ? 問(wèn)題通熄? 如果一個(gè)類(lèi)沒(méi)有實(shí)現(xiàn)接口,那怎么為這個(gè)類(lèi)創(chuàng)建代理對(duì)象呢找都?這時(shí)候就需要使用到Cglib代理了唇辨。
? ?特點(diǎn): 目標(biāo)對(duì)象不需要實(shí)現(xiàn)接口
? ?使用: 1、下載Cglib jar包
? ? ? ? ? ? ? 2能耻、給目標(biāo)對(duì)象創(chuàng)建代理對(duì)象
????????public class ProxyFactoryimplements MethodInterceptor {
????????????private Objecttarget;
? ? ????????public ProxyFactory(Object target) {
????????????????this.target = target;
????????? ? }
????????// 使用cglib給目標(biāo)對(duì)象創(chuàng)建代理對(duì)象
? ? ? ? ? ?public ObjectgetProxyInstance() {
????????????????// 1赏枚、創(chuàng)建工具類(lèi)
? ? ? ????????? Enhancer enhancer =new Enhancer();
? ? ? ? ? ? ? ?// 2、設(shè)置父類(lèi)
? ? ? ? ????????enhancer.setSuperclass(target.getClass());
? ? ? ????????? // 3晓猛、設(shè)置回調(diào)
? ? ? ????????? enhancer.setCallback(this);
? ? ? ????????? // 4饿幅、創(chuàng)建子類(lèi)
? ? ? ????????? return enhancer.create();
? ????????? }
????????@Override
? ????? public Objectintercept(Object o, Method method, Object[] objects, MethodProxy ????????????methodProxy)throws Throwable {
????????????android.util.Log.i("zqr", "on pre save user");
? ? ? ????? Object object = method.invoke(target, objects);
? ? ? ????? android.util.Log.i("zqr", "on After save user");
? ? ? ? return object;
? ? }
}
三、代理模式與適配器模式戒职,裝飾者模式區(qū)別?
???1栗恩、和適配器模式的區(qū)別:適配器模式主要改變所考慮對(duì)象的接口,而代理模式不能改變所代理類(lèi)的接口洪燥。