<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    andy-j2ee  
    JAVA
    公告
    • 在夜深人靜的時候,偶彈起心愛的土琵琶,唱起那動人的歌謠(柯受良-《大哥》):偶寫了代碼好多年,偶不愛冰冷的床沿,不要逼偶想念,不要逼偶流淚,偶會翻。
    日歷
    <2011年10月>
    2526272829301
    2345678
    9101112131415
    16171819202122
    23242526272829
    303112345
    統計
    • 隨筆 - 19
    • 文章 - 1
    • 評論 - 1
    • 引用 - 0

    導航

    常用鏈接

    留言簿

    隨筆分類(5)

    隨筆檔案(19)

    文章分類(1)

    文章檔案(1)

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

     
    原文http://blog.zdnet.com.cn/html/90/289390-838716.htmlJDK動態代理
       
     1 package com.baobaotao.proxy; 在JDK 1.3以后提供了動態代理的技術,允許開發者在運行期創建接口的代理實例。在Sun剛推出動態代理時,還很難想象它有多大的實際用途,現在我們終于發現動態代理是實現AOP的絕好底層技術。
        JDK的動態代理主要涉及到java.lang.reflect包中的兩個類:Proxy和InvocationHandler。其中InvocationHandler是一個接口,可以通過實現該接口定義橫切邏輯,在并通過反射機制調用目標類的代碼,動態將橫切邏輯和業務邏輯編織在一起。
       而Proxy為InvocationHandler實現類動態創建一個符合某一接口的代理實例。這樣講一定很抽象,我們馬上著手動用Proxy和InvocationHandler這兩個魔法戒對上一節中的性能監視代碼進行AOP式的改造。
        首先,我們從業務類ForumServiceImpl 中刪除性能監視的橫切代碼,使ForumServiceImpl只負責具體的業務邏輯,如所示:
    代碼清單 5 ForumServiceImpl:移除性能監視橫切代碼
        
     2 
     3 public class ForumServiceImpl implements ForumService {
     4 
     5  public void removeTopic(int topicId) {
     6          ①
     7   System.out.println("模擬刪除Topic記錄:"+topicId);
     8   try {
     9    Thread.currentThread().sleep(20);
    10   } catch (Exception e) {
    11    throw new RuntimeException(e);
    12   }
    13    ②
    14  }
    15  public void removeForum(int forumId) {
    16          ①
    17   System.out.println("模擬刪除Forum記錄:"+forumId);
    18   try {
    19    Thread.currentThread().sleep(40);
    20   } catch (Exception e) {
    21    throw new RuntimeException(e);
    22   }
    23          ②
    24  }
    25 }
        
    在代碼清單 5中的①和②處,原來的性能監視代碼被移除了,我們只保留了真正的業務邏輯。
        從業務類中移除的橫切代碼當然還得找到一個寄居之所,InvocationHandler就是橫切代碼的家園樂土,我們將性能監視的代碼安置在PerformaceHandler中,如代碼清單 6所示:
    代碼清單 6 PerformaceHandler
     1 package com.baobaotao.proxy;
        
     2 import java.lang.reflect.InvocationHandler;
     3 import java.lang.reflect.Method;
     4 
     5 public class PerformaceHandler implements InvocationHandler {
     6     private Object target;
     7  public PerformaceHandler(Object target){//①target為目標的業務類
     8   this.target = target;
     9  }
    10  public Object invoke(Object proxy, Method method, Object[] args)
    11    throws Throwable {
    12   PerformanceMonitor.begin(target.getClass().getName()+"."+ method.getName());
    13   Object bj = method.invoke(target, args);//②通過反射方法調用目標業務類的業務方法
    14   PerformanceMonitor.end();
    15   return obj;
    16  }
    17 }
        
     粗體部分的代碼為性能監視的橫切代碼,我們發現,橫切代碼只出現一次,而不是原來那樣星灑各處。大家注意②處的method.invoke(),該語句通過反射的機制調用目標對象的方法,這樣InvocationHandler的invoke(Object proxy, Method method, Object[] args)方法就將橫切代碼和目標業務類代碼編織到一起了,所以我們可以將InvocationHandler看成是業務邏輯和橫切邏輯的編織器。下面,我們對這段代碼做進一步的說明。
    首先,我們實現InvocationHandler接口,該接口定義了一個 invoke(Object proxy, Method method, Object[] args)的方法,proxy是代理實例,一般不會用到;method是代理實例上的方法,通過它可以發起對目標類的反射調用;args是通過代理類傳入的方法參數,在反射調用時使用。
        此外,我們在構造函數里通過target傳入真實的目標對象,如①處所示,在接口方法invoke(Object proxy, Method method, Object[] args)里,將目標類實例傳給method.invoke()方法,通過反射調用目標類方法,如②所示。
        下面,我們通過Proxy結合PerformaceHandler創建ForumService接口的代理實例,如代碼清單 7所示:
    代碼清單 7 TestForumService:創建代理實例
     1 package com.baobaotao.proxy;
        
     2 import java.lang.reflect.Proxy;
     3 public class TestForumService {
     4  public static void main(String[] args) {
     5   ForumService target = new ForumServiceImpl();//①目標業務類
     6 //② 將目標業務類和橫切代碼編織到一起
     7   PerformaceHandler handler = new PerformaceHandler(target);
     8          //③為編織了目標業務類邏輯和性能監視橫切邏輯的handler創建代理類
     9   ForumService proxy = (ForumService) Proxy.newProxyInstance(
    10 target.getClass().getClassLoader(),
    11     target.getClass().getInterfaces(),
    12  handler);
    13          //④ 操作代理實例
    14   proxy.removeForum(10);
    15   proxy.removeTopic(1012);
    16  }
    17 }
         
    上面的代碼完成了業務類代碼和橫切代碼編織和接口代理實例生成的工作,其中在②處,我們將ForumService實例編織為一個包含性能監視邏輯的PerformaceHandler實例,然后在③處,通過Proxy的靜態方法newProxyInstance()為融合了業務類邏輯和性能監視邏輯的handler創建一個ForumService接口的代理實例,該方法的第一個入參為類加載器,第二個入參為創建的代理實例所要實現的一組接口,第三個參數是整合了業務邏輯和橫切邏輯的編織器對象。
    按照③處的設置方式,這個代理實例就實現了目標業務類的所有接口,也即ForumServiceImpl的ForumService接口。這樣,我們就可以按照調用ForumService接口的實例相同的方式調用代理實例,如④所示。運行以上的代碼,輸出以下的信息:
        begin monitor
    模擬刪除Forum記錄:10
    end monitor
    com.baobaotao.proxy.ForumServiceImpl.removeForum花費47毫秒。

    begin monitor
    模擬刪除Topic記錄:
    1012
    end monitor
    com.baobaotao.proxy.ForumServiceImpl.removeTopic花費26毫秒。
          
    我們發現,程序的運行效果和直接在業務類中編寫性能監視邏輯的效果一致,但是在這里,原來分散的橫切邏輯代碼已經被我們抽取到PerformaceHandler中。當其它業務類(如UserService、SystemService等)的業務方法也需要使用性能監視時,我們只要按照以上的方式,分別為它們創建代理對象就可以了。下面,我們用時序圖描述調用關系,進一步代理實例的本質,如圖1所示:
        

        
      圖 1代理實例的時序圖
        我們在上圖中特別使用虛線陰影的方式對通過代理器創建的ForumService實例進行凸顯,該實例內部利用PerformaceHandler整合橫切邏輯和業務邏輯。調用者調用代理對象的的removeForum()和removeTopic()方法時,上圖的內部調用時序清晰地告訴了我們實際上所發生的一切。



     


    posted on 2011-10-07 19:29 安多 閱讀(900) 評論(0)  編輯  收藏 所屬分類: S2SH Learning
     
    Copyright © 安多 Powered by: 博客園 模板提供:滬江博客
    主站蜘蛛池模板: 亚洲乱码国产一区三区| jizz免费一区二区三区| 亚洲AV无码一区东京热| 国产一卡二卡≡卡四卡免费乱码| 亚欧免费一级毛片| 成在人线av无码免费高潮水 | 国产精品视频白浆免费视频| 爱情岛论坛亚洲品质自拍视频网站| 亚洲欧洲春色校园另类小说| 国精无码欧精品亚洲一区| 免费一级一片一毛片| 女人18毛片水真多免费播放| 亚洲精品视频在线观看免费| 久久免费国产精品一区二区| 一级毛片免费视频网站| 猫咪免费人成网站在线观看入口| 国产精品亚洲综合久久| 亚洲一卡2卡4卡5卡6卡在线99| 婷婷精品国产亚洲AV麻豆不片| 亚洲色大成网站WWW久久九九| 亚洲国产精品13p| 可以免费观看的一级毛片| 日本免费福利视频| 午夜小视频免费观看| 最新中文字幕免费视频| 免费精品人在线二线三线区别| 免费精品国产自产拍在线观看图片| 免费人成视频在线观看网站 | 久久精品国产精品亚洲人人| 免费大黄网站在线看| 日韩免费一级毛片| 日韩高清免费观看| 免费一级毛片在线播放| 四虎永久免费地址在线网站| 免费看国产精品麻豆| 四虎国产精品免费久久影院| 哒哒哒免费视频观看在线www| 亚洲成人高清在线| 久久久久亚洲爆乳少妇无 | 国产国产人免费人成成免视频| 精品国产福利尤物免费|