您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)如何在Java中利用動態(tài)代理實現(xiàn)應(yīng)用攔截器,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
由于動態(tài)代理一般都比較難理解,程序設(shè)計者會設(shè)計一個攔截器接口供開發(fā)者使用,開發(fā)者只要知道攔截器接口的方法、含義和作用即可,無須知道動態(tài)代理是怎么實現(xiàn)的。用JDK動態(tài)代理來實現(xiàn)一個攔截器的邏輯,為此先定義攔截器接口Interceptor,如下所示:
/** * @Auther: haozz * @Date: 2018/5/27 22:15 * @Description:攔截器接口 **/ public interface Interceptor { boolean before(Object proxy, Object target, Method method,Object[] args); void around(Object proxy,Object target,Method method,Object[] args); void after(Object proxy,Object target,Method method,Object[] args); }
這里定義了3個方法,before、around、after方法,分別給予這些方法如下邏輯定義:
3個方法的參數(shù)為:proxy代理對象、target真實對象、method方法、args運行方法參數(shù);
before方法返回boolean值,它在真實對象前調(diào)用。當(dāng)返回為true時,則反射真實對象的方法;當(dāng)返回為false時,則調(diào)用around方法;
在before方法返回為false的情況下,調(diào)用around方法
在反射真實對象方法或者around方法執(zhí)行之后,調(diào)用after方法
實現(xiàn)這個Interceptor的實現(xiàn)類——MyInterceptor,如下:
/** * @Auther: haozz * @Date: 2018/5/27 22:48 * @Description:MyInterceptor **/ public class MyInterceptor implements Interceptor{ @Override public boolean before(Object proxy, Object target, Method method, Object[] args) { System.out.println("反射方法前邏輯"); return false;//不反射被代理對象原有方法 } @Override public void around(Object proxy, Object target, Method method, Object[] args) { System.out.println("取代了被代理對象的方法"); } @Override public void after(Object proxy, Object target, Method method, Object[] args) { System.out.println("反射方法后邏輯"); } }
它實現(xiàn)了所有Interceptor接口的方法,使用JDK動態(tài)代理,就可以去實現(xiàn)這些方法在適當(dāng)時的調(diào)用邏輯了。以上一篇(Java設(shè)計模式之動態(tài)代理)中的接口和實現(xiàn)類為例,在JDK動態(tài)代理中使用攔截器,如下所示:
/** * @Auther: haozz * @Date: 2018/5/27 22:30 * @Description: **/ public class InterceptorJdkProxy implements InvocationHandler { private Object target;//真實對象 private String interceptorClass = null;//攔截器全限定名 public InterceptorJdkProxy(Object target,String interceptorClass){ this.target = target; this.interceptorClass = interceptorClass; } public static Object bind(Object target,String interceptorClass){ //取得代理對象 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InterceptorJdkProxy(target,interceptorClass)); } @Override /** * Description:通過代理對象調(diào)用方法,首先進(jìn)入這個方法 * @auther: haozz * @param: proxy 代理對象 * @param: method 被調(diào)用方法 * @param: args 方法的參數(shù) * @return: java.lang.Object * @date: 2018/5/27 23:00 **/ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(interceptorClass == null){ //沒有設(shè)置攔截器則直接反射原有方法 return method.invoke(target,args); } Object result = null; //通過反射生成攔截器 Interceptor interceptor = (Interceptor) Class.forName(interceptorClass).newInstance(); //調(diào)用前置方法 if(interceptor.before(proxy,target,method,args)){ //反射原有對象方法 result = method.invoke(target,args); }else{//返回false執(zhí)行around方法 interceptor.around(proxy,target,method,args); } //調(diào)用后置方法 interceptor.after(proxy,target,method,args); return result; } }
這里有兩個屬性,一個是target,它是真實對象;另一個是字符串interceptorClass,它是一個攔截器的全限定名。解釋以下這段代碼的執(zhí)行步驟:
第1步,在bind方法中用JDK動態(tài)代理綁定了一個對象,然后返回代理對象;
第2步,如果沒有設(shè)置攔截器,則直接反射真實對象的方法,然后結(jié)束,否則進(jìn)行第3步;
第3步,通過反射生成攔截器,并準(zhǔn)備使用它;
第4步,調(diào)用攔截器的before方法,如果返回為true,反射原來的方法;否則運行攔截器的around方法;
第5步,調(diào)用攔截器的after方法;
第6步,返回結(jié)果。
開發(fā)者只要知道攔截器的作用就可以編寫攔截器了,編寫完后可以設(shè)置攔截器,這樣就完成了任務(wù),所以對于開發(fā)者而言相對簡單了
設(shè)計者可能是精通Java的開發(fā)人員,他來完成動態(tài)代理的邏輯
設(shè)計者只會把攔截器接口暴露給開發(fā)者使用,讓動態(tài)代理的邏輯在開發(fā)者的視野中“消失”
攔截器可以進(jìn)一步簡化動態(tài)代理的使用方法,使程序變得更簡單,用如下的測試類測試一下:
public class Mytest { public static void main(String []args){ HelloWorld proxy1 = (HelloWorld) InterceptorJdkProxy.bind(new HelloWorldImpl(),"com.csdn.blog.interceptor.MyInterceptor"); proxy1.sayHelloWorld(); } }
運行這段代碼,得到以下結(jié)果:
反射方法前邏輯
取代了被代理對象的方法
反射方法后邏輯
關(guān)于如何在Java中利用動態(tài)代理實現(xiàn)應(yīng)用攔截器就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。