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

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

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

    最愛Java

    書山有路勤為徑,學海無涯苦作舟

    《AspectJ Cookbook》讀書筆記四: 捕獲方法上的連接點

    一. 捕獲方法調用
            
    使用call(Signature)切入點。其語法:
             pointcut <pointcut name>(<any values to be picked up>) : 
                call (<optional modifier> <return type> <class>.<method>(<paramater type>));
             1. 在方法調用上觸發通知,其環境是調用類。
             2. Signature可以包含通配符,用于選擇不同類和方法上的一系列連接點。
    具有通配符的簽名 描述
    * void MyClass.foo(int , float) 無論修飾符是什么,都會捕獲方法上的連接點。也可以忽略修飾符的可見性來做到這一點。
    void MyClass.foo(int , float)
    * * MyClass.foo(int , float) 無論修飾符或返回類型是什么,都會捕獲方法上的連接點。
    * MyClass.foo(int , float)
    * * *.foo(int , float) 無論修飾符,返回類型或類是什么,都會捕獲方法上的連接點。
    * *.foo(int , float)
    * * *.*(int , float) 無論修飾符,返回類型,類或者方法是什么,都會捕獲方法上的連接點。
    * * *.*(* , float) 無論修飾符,返回類型,類,或者其中的參數包含任何內容并且后接一個浮點數的方法是什么,都會捕獲方法上的連接點。
    * * *.*(* , ..) 無論修飾符,返回類型,類,或者其中的參數包含至少一個單值并且后接任意數量的方法是什么,都會捕獲方法上的連接點。
    * * *.*(..) 無論修飾符,返回類型,類,或者其中有任意數量參數的方法是什么,都會捕獲方法上的連接點。
    * *(..)
    * mypackage..*.*(..) 捕獲mypackage包和子包內的任何方法上的連接點。
    * MyClass+.*(..) 捕獲MyClass和任何子類中任何方法上的連接點。
        
            我們來看一個最簡單的例子:
    package com.aspectj;

    public aspect CallRecipe {
        
    /*
         * Specifies calling advice whenever a mehtod
         * matching the following rules gets called:
         * 
         * Class Name: MyClass
         * Method Name: foo
         * Method Return Type: void
         * Method Parameters: an int followed by a String
         
    */

        pointcut callPointCut() : call(
    void MyClass.foo(int , String));
        
        
    //Advice declaration
        before() : callPointCut() {
            System.out.println(
    "------------------- Aspect Advice Logic -------------------");
            System.out.println(
    "In the advice attached to the call point cut");
            System.out.println(
    "Actually executing before the point cut call");
            System.out.println(
    "But that's a recipe for Chapter 6!");
            System.out.println(
    "signature: " + thisJoinPoint.getStaticPart().getSignature());
            System.out.println(
    "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
            System.out.println(
    "------------------------------------------");
        }


    }

        
        這樣的一個方面可能執行下來的結果是這樣的:

    ------------------- Aspect Advice Logic -------------------
    In the advice attached to the call point cut
    Actually executing before the point cut call
    But that's a recipe for Chapter 6!
    signature: void com.aspectj.MyClass.foo(int, String)
    Source Line: MyClass.java:10
    -----------------------------------------------------------

    foo(int , String)

     

            這里有一個報告需要提醒一下。我們先運行如下代碼:

    package com.aspectj;

    public class Test extends MyClass{
        
    public void foo(int age , String name) {
            System.out.println(
    "foo(int , String)");
        }

        
        
    public static void main(String[] args) {
            Test c 
    = new Test();
            c.foo(
    3 , "name");
        }


    }

            Test.java是MyClass.java的子類,并重寫了foo(int , String)方法。按照Java正常的執行方法,運行Test.java是不會牽涉到任何方面的,但事實相反,callPointCut()通知還是會被執行。這就是AspectJ設計的比較妖怪的地方。對此,http://www.eecs.ucf.edu/~leavens/FOAL/papers-2004/barzilay-etal.pdf 有詳細的描述。有興趣的朋友可以研究一把。
    /Files/zhengzhili/Call_and_Execution_Semantics_in_AspectJ.pdf
    二. 捕獲方法調用上傳遞的參數值
        
    可以使用call(Signature)和args([TypePatterns | Identifiers])切入點來捕獲對方法的調用,然后把需要的標識符綁定到方法的參數值上。

    package com.aspectj;

    public aspect CaptureCallPamaterRrecipe {
        
    /*
         * Specifies calling advice whenever a mehtod
         * matching the following rules gets called:
         * 
         * Class Name: MyClass
         * Method Name: foo
         * Method Return Type: void
         * Method Parameters: an int followed by a String
         
    */

        pointcut captureCallPamaters(
    int value , String name) : call(void MyClass.foo(int , String)) && args(value , name);
        
        
        
    //Advice declaration
        before(int value , String name) : captureCallPamaters(value , name) {
            System.out.println(
    "------------------- Aspect Advice Logic -------------------");
            System.out.println(
    "In the advice attached to the call point cut");
            System.out.println(
    "Captured int parameter on method: " + value);
            System.out.println(
    "Captured String parameter on method: " + name);
            System.out.println(
    "------------------------------------------");
        }
        
    }

            上例中個人理解為兩次綁定過程。第一次captureCallPamaters通過args([Types | Identifiers])將foo方法的參數綁定到自己的參數上;第二次再把自己的參數綁定到before()上。也因此,1. pointcut captureCallPamaters(int value , String name) : call(void MyClass.foo(int , String)) && args(value , name); 中參數名必須一一對應;2.before(int value , String name) : captureCallPamaters(value , name) 中參數名也必須一一對應。而1和2之間的參數名則不需要一一對應。

    三. 捕獲方法調用的目標
            
    使用call(Signature)和targer([Type | Identifier])切入點來捕獲方法的調用,然后把單一標識符綁定到正在調用方法的對象上。

    package com.aspectj;


    public aspect CaptureCallTargetRecipe 
    {
        
    /*
         * Specifies calling advice whenever a method
         * matching the following rules gets called:
         * 
         * Class Name: MyClass
         * Method Name: foo
         * Method Return Type: void
         * Method Parameters: an int followed by a String
         
    */

        pointcut captureCallTarget(MyClass myObject) : call(
    void MyClass.foo(int , String)) && target(myObject);
        
        
        
    //Advice declaration

        before(MyClass myObject) : captureCallTarget(myObject) {
            System.out.println(
    "------------------- Aspect Advice Logic -------------------"
    );
            System.out.println(
    "In the advice attached to the call point cut"
    );
            System.out.println(
    "Captured target object for the method call: " +
     myObject);
            System.out.println(
    "------------------------------------------"
    );
        }
        
    }


    四. 當執行一個方法時捕獲它
            
    使用execution(Signature)切入點。其語法如下:
            pointcut <pointcut name>(<any values to be picked up>) :
                execution(<optional modifier> <return type> <class>.<method>(<paramater types>));
            execution(Signature)切入點具有兩個關鍵特征:
            1。觸發連接點的環境在目標類方法中。
            2。Signature可以包含通配符,以選擇不同類和方法上的一系列連接點。

    package com.aspectj;

    public aspect ExecutionRecipe {
        
    /*
         * Specifies calling advice whenever a method
         * matching the following rules gets called:
         * 
         * Class Name: MyClass
         * Method Name: foo
         * Method Return Type: void
         * Method Parameters: an int followed by a String
         
    */

        pointcut executionPointcut() : execution(
    void MyClass.foo(int , String));
        
        
        
    //Advice declaration
        before() : executionPointcut() && !within(ExecutionRecipe +{
            System.out.println(
    "------------------- Aspect Advice Logic -------------------");
            System.out.println(
    "In the advice picked by ExecutionRecipe");
            System.out.println(
    "signature: " + thisJoinPoint.getStaticPart().getSignature());
            System.out.println(
    "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
            System.out.println(
    "------------------------------------------");
        }
        
    }

            上述代碼和第一部分所使用的call(Signature)切入點相比,沒什么新的內容。但請注意是什么地方調用通知,以及它的環境是什么。即請特別關注thisJoinPoint.getStaticPart().getSourceLocation()的返回值。
            
    五. 在執行方法時捕獲this引用的值 
           在執行期間捕獲方法時,想通過顯示Java的this引用所指向的對象,使之可以被通知使用,可以使用execute(Signature)和this(Type | Identifier)切入點來捕獲方法的執行,并把單一標識符綁定到方式執行期間this引用所指向的對象。

    package com.aspectj;

    public aspect CaptureThisReferenceRecipe {
        
    /*
         * Specifies calling advice whenever a mehtod
         * matching the following rules gets called:
         * 
         * Class Name: MyClass
         * Method Name: foo
         * Method Return Type: void
         * Method Parameters: an int followed by a String
         
    */

        pointcut captureThisDuringExecution(MyClass myObject) :
            execution(
    void MyClass.foo(int , String)) && this (myObject);
        
        
    //Advice declaration
        before(MyClass myObject) : captureThisDuringExecution(myObject) {
            System.out.println(
    "------------------- Aspect Advice Logic -------------------");
            System.out.println(
    "In the advice attached to the execute point cut");
            System.out.println(
    "Captured this reference: " + myObject);
            System.out.println(
    "------------------------------------------");        
        }

    }

    posted on 2008-07-03 22:17 Brian 閱讀(1518) 評論(2)  編輯  收藏 所屬分類: 《AspectJ Cookbook》讀書筆記

    評論

    # re: 《AspectJ Cookbook》讀書筆記四: 捕獲方法上的連接點 2008-07-03 23:05 lvq810

    怎么沒三?  回復  更多評論   

    # re: 《AspectJ Cookbook》讀書筆記四: 捕獲方法上的連接點[未登錄] 2008-07-04 00:37 呵呵

    學習了  回復  更多評論   

    公告


    導航

    <2008年7月>
    293012345
    6789101112
    13141516171819
    20212223242526
    272829303112
    3456789

    統計

    常用鏈接

    留言簿(4)

    隨筆分類

    隨筆檔案

    收藏夾

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: a毛片免费全部播放完整成| 亚洲av无码成人影院一区| 日韩成人在线免费视频| 亚洲成人一级电影| 国产亚洲福利精品一区二区| 国产一级a毛一级a看免费人娇 | 欧洲乱码伦视频免费国产 | 亚洲免费观看网站| 免费黄色毛片视频| 亚洲AV成人无码久久WWW| 永久黄网站色视频免费| 国产综合激情在线亚洲第一页| 日韩午夜免费视频| 日韩精品免费一线在线观看| 久久亚洲国产精品123区| 国产区在线免费观看| 久久精品国产亚洲AV网站| 久久久免费精品re6| 亚洲视频一区在线| 成人免费毛片观看| 日本在线观看免费高清| 久久精品夜色噜噜亚洲A∨| 不卡视频免费在线观看| 亚洲视频在线观看网站| 在线a级毛片免费视频| 真正全免费视频a毛片| 亚洲女初尝黑人巨高清| 无遮挡a级毛片免费看| 久久亚洲精品视频| 在线观看H网址免费入口| 亚洲精品无码mⅴ在线观看| 亚洲国产精品美女久久久久| 免费在线精品视频| 久久爰www免费人成| 亚洲精品无码不卡在线播HE | 亚洲综合av一区二区三区| 无码不卡亚洲成?人片| 亚洲日本天堂在线| 国产日产亚洲系列最新| 久热中文字幕在线精品免费| 无码天堂va亚洲va在线va|