您好,登錄后才能下訂單哦!
什么是代理模式?
代理模式:在調(diào)用處不直接調(diào)用目標(biāo)類(lèi)進(jìn)行操作,而是調(diào)用代理類(lèi),然后通過(guò)代理類(lèi)來(lái)調(diào)用目標(biāo)類(lèi)進(jìn)行操作。在代理類(lèi)調(diào)用目標(biāo)類(lèi)的前后可以添加一些預(yù)處理和后處理操作來(lái)完成一些不屬于目標(biāo)類(lèi)的功能。
為什么要使用代理模式?
通過(guò)代理模式可以實(shí)現(xiàn)對(duì)目標(biāo)類(lèi)調(diào)用的控制、在目標(biāo)類(lèi)調(diào)用前/后進(jìn)行一些不屬于目標(biāo)類(lèi)的操作,如:數(shù)據(jù)驗(yàn)證、預(yù)處理、后處理、異常處理等
什么是靜態(tài)代理什么是動(dòng)態(tài)代理?
jdk代理和cglib代理區(qū)別在哪里?
不同點(diǎn):jdk動(dòng)態(tài)代理的目標(biāo)類(lèi)必須實(shí)現(xiàn)的有接口,因?yàn)樵谡{(diào)用Proxy.newProxyInstance()的時(shí)候需要傳入目標(biāo)類(lèi)的接口類(lèi)。而cglib不做此限制。
下面看代碼分析:
定義一個(gè)Person接口
package com.zpj.designMode.proxy; //定義一個(gè)Person接口 public interface Person { public void doWork(); }
添加一個(gè)實(shí)現(xiàn)類(lèi):MrLi
package com.zpj.designMode.proxy; //添加一個(gè)實(shí)現(xiàn)類(lèi) public class MrLi implements Person { @Override public void doWork() { System.out.println("-----doWork"); } }
靜態(tài)代理:
添加一個(gè)靜態(tài)代理類(lèi)Proxy
package com.zpj.designMode.proxy; //靜態(tài)代理,代理必須和目標(biāo)類(lèi)實(shí)現(xiàn)共同的接口 public class Proxy implements Person { private Person person;// 被代理人 //這里的目標(biāo)類(lèi)型決定了該代理類(lèi)只能代理實(shí)現(xiàn)了Person接口的實(shí)例,而不能接收其他類(lèi)型參數(shù),這也就是靜態(tài)代理的局限性 public Proxy(Person person) { this.person = person; } @Override public void doWork() { System.out.println("doSomething-----start"); person.doWork(); System.out.println("doSomething-----end"); } }
靜態(tài)代理測(cè)試程序:
package com.zpj.designMode.proxy; public class Run { public static void main(String[] args) { MrLi li = new MrLi(); Proxy proxy = new Proxy(li); //調(diào)用處直接調(diào)用代理進(jìn)行目標(biāo)方法的操作。 proxy.doWork(); } }
JDK動(dòng)態(tài)代理:
添加一個(gè)代理JDKProxy,該代理實(shí)現(xiàn)InvocationHandler接口且覆寫(xiě)invoke方法。
package com.zpj.designMode.proxy.jdk; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /*** @author Perkins Zhu @date 2017年3月13日 上午8:41:10 */ public class JDKProxy implements InvocationHandler { private Object person;// 被代理人 //這里的目標(biāo)類(lèi)型為Object,則可以接受任意一種參數(shù)作為被代理類(lèi),實(shí)現(xiàn)了動(dòng)態(tài)代理。但是要注意下面的newProxyInstance()中的參數(shù) public Object getInstance(Object person) { this.person = person; //與cglib的區(qū)別在于這里構(gòu)建代理對(duì)象的時(shí)候需要傳入被代理對(duì)象的接口對(duì)象,第二個(gè)參數(shù)。而cglib不需要被代理對(duì)象實(shí)現(xiàn)任何接口即可 return Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("doSomething---------start"); method.invoke(person, args); System.out.println("doSomething---------end"); return null; } }
JDK動(dòng)態(tài)代理測(cè)試程序
package com.zpj.designMode.proxy.jdk; import com.zpj.designMode.proxy.MrLi; import com.zpj.designMode.proxy.Person; /*** * @author Perkins Zhu * @date 2017年3月13日 上午8:51:31 */ public class Run { public static void main(String[] args) { Person person = (Person) new JDKProxy().getInstance(new MrLi()); //注意這里的person不是目標(biāo)類(lèi)person,而是代理類(lèi)person:debug的時(shí)候顯示null,有'$'標(biāo)識(shí)符 person.doWork(); } }
Cglib動(dòng)態(tài)代理:
添加一個(gè)CglibProxy代理,同時(shí)實(shí)現(xiàn)MethodInterceptor接口。
package com.zpj.designMode.proxy.cglib; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /*** * @author Perkins Zhu * @date 2017年3月13日 上午9:02:54 */ public class CglibProxy implements MethodInterceptor { private Object targetObject; // 這里的目標(biāo)類(lèi)型為Object,則可以接受任意一種參數(shù)作為被代理類(lèi),實(shí)現(xiàn)了動(dòng)態(tài)代理 public Object getInstance(Object target) { this.targetObject = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this); //注意該處代理的創(chuàng)建過(guò)程 Object proxyObj = enhancer.create(); return proxyObj;// 返回代理對(duì)象 } @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object obj = null; System.out.println("doSomething---------start"); obj = method.invoke(targetObject, args); System.out.println("doSomething---------end"); return obj; } }
Cglib動(dòng)態(tài)代理測(cè)試程序
package com.zpj.designMode.proxy.cglib; import com.zpj.designMode.proxy.MrLi; import com.zpj.designMode.proxy.Person; /*** @author Perkins Zhu @date 2017年3月13日 上午9:07:38 */ public class Run { public static void main(String[] args) { Person person = (Person)new CglibProxy().getInstance(new MrLi()); person.doWork(); } }
仔細(xì)對(duì)比Proxy、CglibProxy和JDKProxy區(qū)分靜態(tài)代理、JDK動(dòng)態(tài)代理和Cglib動(dòng)態(tài)代理的異同點(diǎn)!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。