91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在Java中利用動態代理實現應用攔截器

發布時間:2021-06-09 17:57:06 來源:億速云 閱讀:111 作者:Leah 欄目:編程語言

這篇文章將為大家詳細講解有關如何在Java中利用動態代理實現應用攔截器,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

由于動態代理一般都比較難理解,程序設計者會設計一個攔截器接口供開發者使用,開發者只要知道攔截器接口的方法、含義和作用即可,無須知道動態代理是怎么實現的。用JDK動態代理來實現一個攔截器的邏輯,為此先定義攔截器接口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方法,分別給予這些方法如下邏輯定義:

  1. 3個方法的參數為:proxy代理對象、target真實對象、method方法、args運行方法參數;

  2. before方法返回boolean值,它在真實對象前調用。當返回為true時,則反射真實對象的方法;當返回為false時,則調用around方法;

  3. 在before方法返回為false的情況下,調用around方法

  4. 在反射真實對象方法或者around方法執行之后,調用after方法

實現這個Interceptor的實現類——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("反射方法后邏輯");
  }
}

它實現了所有Interceptor接口的方法,使用JDK動態代理,就可以去實現這些方法在適當時的調用邏輯了。以上一篇(Java設計模式之動態代理)中的接口和實現類為例,在JDK動態代理中使用攔截器,如下所示:

/**
 * @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:通過代理對象調用方法,首先進入這個方法
   * @auther: haozz
   * @param: proxy 代理對象
   * @param: method 被調用方法
   * @param: args 方法的參數
   * @return: java.lang.Object
   * @date: 2018/5/27 23:00
   **/
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if(interceptorClass == null){
      //沒有設置攔截器則直接反射原有方法
      return method.invoke(target,args);
    }
    Object result = null;
    //通過反射生成攔截器
    Interceptor interceptor = (Interceptor) Class.forName(interceptorClass).newInstance();
    //調用前置方法
    if(interceptor.before(proxy,target,method,args)){
      //反射原有對象方法
      result = method.invoke(target,args);
    }else{//返回false執行around方法
      interceptor.around(proxy,target,method,args);
    }
    //調用后置方法
    interceptor.after(proxy,target,method,args);
    return result;
  }
}

這里有兩個屬性,一個是target,它是真實對象;另一個是字符串interceptorClass,它是一個攔截器的全限定名。解釋以下這段代碼的執行步驟:

        第1步,在bind方法中用JDK動態代理綁定了一個對象,然后返回代理對象;

        第2步,如果沒有設置攔截器,則直接反射真實對象的方法,然后結束,否則進行第3步;

        第3步,通過反射生成攔截器,并準備使用它;

        第4步,調用攔截器的before方法,如果返回為true,反射原來的方法;否則運行攔截器的around方法;

        第5步,調用攔截器的after方法;

        第6步,返回結果。

  • 開發者只要知道攔截器的作用就可以編寫攔截器了,編寫完后可以設置攔截器,這樣就完成了任務,所以對于開發者而言相對簡單了

  • 設計者可能是精通Java的開發人員,他來完成動態代理的邏輯

  • 設計者只會把攔截器接口暴露給開發者使用,讓動態代理的邏輯在開發者的視野中“消失”

攔截器可以進一步簡化動態代理的使用方法,使程序變得更簡單,用如下的測試類測試一下:

public class Mytest {
  public static void main(String []args){
    HelloWorld proxy1 = (HelloWorld) InterceptorJdkProxy.bind(new HelloWorldImpl(),"com.csdn.blog.interceptor.MyInterceptor");
    proxy1.sayHelloWorld();
  }
}

運行這段代碼,得到以下結果:

反射方法前邏輯
取代了被代理對象的方法
反射方法后邏輯

關于如何在Java中利用動態代理實現應用攔截器就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

民丰县| 大厂| 襄汾县| 贵港市| 钦州市| 驻马店市| 新闻| 舟曲县| 富源县| 双桥区| 嘉禾县| 蛟河市| 夏河县| 子洲县| 玉山县| 东明县| 呼图壁县| 上犹县| 闵行区| 沙河市| 乐安县| 鸡泽县| 遂宁市| 浦北县| 嵊泗县| 麻阳| 资溪县| 淮滨县| 玉林市| 彰武县| 宣恩县| 会理县| 石景山区| 景德镇市| 高尔夫| 尼勒克县| 习水县| 临海市| 芦溪县| 万全县| 安义县|