最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java動(dòng)態(tài)代理之?dāng)r截器的應(yīng)用

 更新時(shí)間:2019年01月16日 09:21:40   作者:Haozz_1994  
今天小編就為大家分享一篇關(guān)于Java動(dòng)態(tài)代理之?dāng)r截器的應(yīng)用,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧

由于動(dòng)態(tài)代理一般都比較難理解,程序設(shè)計(jì)者會(huì)設(shè)計(jì)一個(gè)攔截器接口供開(kāi)發(fā)者使用,開(kāi)發(fā)者只要知道攔截器接口的方法、含義和作用即可,無(wú)須知道動(dòng)態(tài)代理是怎么實(shí)現(xiàn)的。用JDK動(dòng)態(tài)代理來(lái)實(shí)現(xiàn)一個(gè)攔截器的邏輯,為此先定義攔截器接口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個(gè)方法,before、around、after方法,分別給予這些方法如下邏輯定義:

  1. 3個(gè)方法的參數(shù)為:proxy代理對(duì)象、target真實(shí)對(duì)象、method方法、args運(yùn)行方法參數(shù);
  2. before方法返回boolean值,它在真實(shí)對(duì)象前調(diào)用。當(dāng)返回為true時(shí),則反射真實(shí)對(duì)象的方法;當(dāng)返回為false時(shí),則調(diào)用around方法;
  3. 在before方法返回為false的情況下,調(diào)用around方法
  4. 在反射真實(shí)對(duì)象方法或者around方法執(zhí)行之后,調(diào)用after方法

實(shí)現(xiàn)這個(gè)Interceptor的實(shí)現(xiàn)類(lèi)——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;//不反射被代理對(duì)象原有方法
  }
  @Override
  public void around(Object proxy, Object target, Method method, Object[] args) {
    System.out.println("取代了被代理對(duì)象的方法");
  }
  @Override
  public void after(Object proxy, Object target, Method method, Object[] args) {
    System.out.println("反射方法后邏輯");
  }
}

它實(shí)現(xiàn)了所有Interceptor接口的方法,使用JDK動(dòng)態(tài)代理,就可以去實(shí)現(xiàn)這些方法在適當(dāng)時(shí)的調(diào)用邏輯了。以上一篇(Java設(shè)計(jì)模式之動(dòng)態(tài)代理)中的接口和實(shí)現(xiàn)類(lèi)為例,在JDK動(dòng)態(tài)代理中使用攔截器,如下所示:

/**
 * @Auther: haozz
 * @Date: 2018/5/27 22:30
 * @Description:
 **/
public class InterceptorJdkProxy implements InvocationHandler {
  private Object target;//真實(shí)對(duì)象
  private String interceptorClass = null;//攔截器全限定名
  public InterceptorJdkProxy(Object target,String interceptorClass){
    this.target = target;
    this.interceptorClass = interceptorClass;
  }
  public static Object bind(Object target,String interceptorClass){
    //取得代理對(duì)象
    return Proxy.newProxyInstance(target.getClass().getClassLoader(),
        target.getClass().getInterfaces(),
        new InterceptorJdkProxy(target,interceptorClass));
  }
  @Override
  /**
   * Description:通過(guò)代理對(duì)象調(diào)用方法,首先進(jìn)入這個(gè)方法
   * @auther: haozz
   * @param: proxy 代理對(duì)象
   * @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){
      //沒(méi)有設(shè)置攔截器則直接反射原有方法
      return method.invoke(target,args);
    }
    Object result = null;
    //通過(guò)反射生成攔截器
    Interceptor interceptor = (Interceptor) Class.forName(interceptorClass).newInstance();
    //調(diào)用前置方法
    if(interceptor.before(proxy,target,method,args)){
      //反射原有對(duì)象方法
      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;
  }
}

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

        第1步,在bind方法中用JDK動(dòng)態(tài)代理綁定了一個(gè)對(duì)象,然后返回代理對(duì)象;

        第2步,如果沒(méi)有設(shè)置攔截器,則直接反射真實(shí)對(duì)象的方法,然后結(jié)束,否則進(jìn)行第3步;

        第3步,通過(guò)反射生成攔截器,并準(zhǔn)備使用它;

        第4步,調(diào)用攔截器的before方法,如果返回為true,反射原來(lái)的方法;否則運(yùn)行攔截器的around方法;

        第5步,調(diào)用攔截器的after方法;

        第6步,返回結(jié)果。

  • 開(kāi)發(fā)者只要知道攔截器的作用就可以編寫(xiě)攔截器了,編寫(xiě)完后可以設(shè)置攔截器,這樣就完成了任務(wù),所以對(duì)于開(kāi)發(fā)者而言相對(duì)簡(jiǎn)單了
  • 設(shè)計(jì)者可能是精通Java的開(kāi)發(fā)人員,他來(lái)完成動(dòng)態(tài)代理的邏輯
  • 設(shè)計(jì)者只會(huì)把攔截器接口露給開(kāi)發(fā)者使用,讓動(dòng)態(tài)代理的邏輯在開(kāi)發(fā)者的視野中“消失”

攔截器可以進(jìn)一步簡(jiǎn)化動(dòng)態(tài)代理的使用方法,使程序變得更簡(jiǎn)單,用如下的測(cè)試類(lèi)測(cè)試一下:

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

運(yùn)行這段代碼,得到以下結(jié)果:

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

顯然,攔截器已經(jīng)生效。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接

相關(guān)文章

  • java實(shí)現(xiàn)桌面右下角彈窗效果

    java實(shí)現(xiàn)桌面右下角彈窗效果

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)桌面右下角彈窗效果,模仿類(lèi)似于qq消息彈窗,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • Java Runtime類(lèi)詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java Runtime類(lèi)詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Runtime類(lèi)封裝了運(yùn)行時(shí)的環(huán)境。每個(gè) Java 應(yīng)用程序都有一個(gè) Runtime 類(lèi)實(shí)例,使應(yīng)用程序能夠與其運(yùn)行的環(huán)境相連接。下面通過(guò)本文給大家分享Java Runtime類(lèi)詳解,需要的朋友參考下吧
    2017-04-04
  • 使用synchronized實(shí)現(xiàn)一個(gè)Lock代碼詳解

    使用synchronized實(shí)現(xiàn)一個(gè)Lock代碼詳解

    這篇文章主要介紹了使用synchronized實(shí)現(xiàn)一個(gè)Lock代碼詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Java將byte[]轉(zhuǎn)圖片存儲(chǔ)到本地的案例

    Java將byte[]轉(zhuǎn)圖片存儲(chǔ)到本地的案例

    這篇文章主要介紹了Java將byte[]轉(zhuǎn)圖片存儲(chǔ)到本地的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-10-10
  • Mybatis枚舉類(lèi)型轉(zhuǎn)換源碼分析

    Mybatis枚舉類(lèi)型轉(zhuǎn)換源碼分析

    在Mybatis的TypeHandlerRegistry中,添加了常用的類(lèi)轉(zhuǎn)換器,其中默認(rèn)的枚舉類(lèi)型轉(zhuǎn)換器是EnumTypeHandler,這篇文章主要介紹了Mybatis枚舉類(lèi)型轉(zhuǎn)換源碼分析,需要的朋友可以參考下
    2024-05-05
  • 基于jQuery獲取table數(shù)據(jù)發(fā)送到后端

    基于jQuery獲取table數(shù)據(jù)發(fā)送到后端

    這篇文章主要介紹了基于jQuery獲取table數(shù)據(jù)發(fā)送到后端,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • java棧實(shí)現(xiàn)二叉樹(shù)的非遞歸遍歷的示例代碼

    java棧實(shí)現(xiàn)二叉樹(shù)的非遞歸遍歷的示例代碼

    這篇文章主要介紹了java棧實(shí)現(xiàn)二叉樹(shù)的非遞歸遍歷,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • Mybatis中自定義TypeHandler處理枚舉詳解

    Mybatis中自定義TypeHandler處理枚舉詳解

    本文主要介紹了Mybatis中自定義TypeHandler處理枚舉的相關(guān)知識(shí)。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-02-02
  • mybatis 事務(wù)回滾配置操作

    mybatis 事務(wù)回滾配置操作

    這篇文章主要介紹了mybatis 事務(wù)回滾配置操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • SpringBoot集成RocketMQ的使用示例

    SpringBoot集成RocketMQ的使用示例

    RocketMQ是阿里巴巴開(kāi)源的一款消息中間件,性能優(yōu)秀,功能齊全,被廣泛應(yīng)用在各種業(yè)務(wù)場(chǎng)景,本文就來(lái)介紹一下SpringBoot集成RocketMQ的使用示例,感興趣的可以了解一下
    2023-11-11

最新評(píng)論

塔河县| 青铜峡市| 迭部县| 东辽县| 五河县| 七台河市| 娱乐| 紫阳县| 元阳县| 登封市| 孟津县| 漾濞| 兴文县| 尉氏县| 大同市| 九寨沟县| 新昌县| 泾阳县| 双流县| 襄垣县| 祁阳县| 凤山市| 黎平县| 固阳县| 清丰县| 曲松县| 容城县| 吉水县| 曲靖市| 法库县| 古丈县| 尼玛县| 定州市| 额济纳旗| 商水县| 和政县| 宁国市| 韶山市| 织金县| 谢通门县| 太保市|