最愛Java

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

          《AspectJ Cookbook》讀書筆記十一: 捕獲基于對象的連接點

                   this([Type | Identifier])研究的是在捕捉的連接點處由this引用的對象的類型。連接點的目標(通過target([Type | Identifier])切入點指定)依賴于連接點類型而有所不同,但它常常是在其上調用方法的對象,或者是以某種方式訪問的在其中遇到連接點的屬性。連接點args(通過args([Types | identieters])切入點指定)就是在捕捉的連接點處可用的參數。
                    可以用兩種方式之一研究this,target和args引用的類型:使用靜態Type指示,或者使用一個Identifier,它引用一個實際的運行時對象。
                    Type指示對連接點處的對象類型提供了一個靜態編譯時評估,并且采用完全限定類名的形式(例如,com.oreilly.Foo是可接受的,但是Foo或Foo.class則不可接受)。
                    Identifiers提供了一種方法,可以通過它來評估連接點處的運行時對象的實際類型,而不僅僅是靜態類型。Identifier在運行時動態地賦予合適的對象。
           
          一. 捕獲何時this引用一個特定的類型問題
              使用this([Type | Identifier])切入點。this([Type | Identifier])切入點的語法如下:
              point <pointcut name>(<any values to be picked up>):this(<type> or <identifier> or *);

              this([Type | Identifier])切入點檢查捕獲的連接點處的this引用,以決定是否調用關聯的通知,它具有5個關鍵特征:
              1. 當執行對象是指定的類型時,this([Type | Identifier])切入點會捕獲所有連接點。
              2. Type定義參數必須解析成有效的類。它不同于TypePattern,TypePattern中可能使用通配符。
              3. Identifier用于檢查this引用的運行時對象的類型,以及根據需要把那個對象展示給通知。
              4. 使用*通配符允許指定一個有效的對象,連接點處的this引用必須指向它,但是你對它是什么類型不感興趣。
              5. 出現在異常處理上的連接點不具有使用handler(TypePattern)切入點的值,當他們使用任何靜態代碼塊(包含使用staticinitialization(TypePattern)切入點指定的靜態類初始化)內的handler(TypePattern),并且有趣地使用preinitializations(Signature)切入點預初始化對象時,它們將不具有使用this([Type|Identifier])切入點展示this引用的值。

              以下展示了this([Type | Identifier])切入點的兩個示例:
                  1.當this引用指向MyClass類型的對象時,使用Identifier捕獲連接點
                  2.當this引用的類型是AnotherClass時,使用Type指示捕獲


           

          package com.aspectj;

          public aspect ThisRecipe {
              
          /**
               * Specifies calling advice whenever the executing
               * object is of a type that matches the following rules:
               * 
               * Identifiers:MyClass object
               
          */

              pointcut thisIdentifierMyClassPointcut(MyClass object):
          this(object);
              
          /**
               * Specifies calling advice whenever the executing
               * object is of a type that matches the following rules:
               * 
               * Type Pattern:AnotherClass
               
          */
              
              pointcut thisTypePatternAnotherClassPointcut():
          this(AnotherClass);
              
              
          //Advice declaration
              before(MyClass object) : thisIdentifierMyClassPointcut(object) && !within(ThisRecipe+{
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by thisIdentifierMyClassPointcut()");
                  System.out.println(
          "Join Point Kind" + thisJoinPoint.getKind());
                  System.out.println(
          "this reference as passed by identifier " + object);
                  System.out.println(
          "Object referenced by this: " + thisJoinPoint.getThis());
                  System.out.println(
          "Signature: " + thisJoinPoint.getStaticPart().getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
                  System.out.println(
          "-----------------------------------------");        
              }

              
              
          //Advice declaration
              before() : thisTypePatternAnotherClassPointcut() && !within(ThisRecipe+{
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by thisIdentifierMyClassPointcut()");
                  System.out.println(
          "Join Point Kind" + thisJoinPoint.getKind());
                  System.out.println(
          "Type of executing object: " + thisJoinPoint.getThis().getClass().getName());
                  System.out.println(
          "Object referenced by this: " + thisJoinPoint.getThis());
                  System.out.println(
          "Signature: " + thisJoinPoint.getStaticPart().getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
                  System.out.println(
          "-----------------------------------------");        
              }


          }



          二. 捕獲何時連接點的目標對象是特定的類型
              使用target([Type|Identifier])切入點。target([Type|Identifier])切入點的語法如下:
              pointcut <pointcut name>(<any values to be picked up>) : target(<type> or <identifier> or *);
              target([Type|Identifier])切入點具有5個關鍵特征:
                  1.當目標對象是特定的類型時,target([Type|Identifier])切入點將選擇所有的連接點。
                  2.Type定義參數必須解析成有效的類,以選擇相關的連接點。它有別與TypePattern,TypePattern中可能使用通配符。
                  3.Identifier用于檢查在捕捉的連接點處被引用為目標的運行時對象的類型,并根據需要把那個對象展示給通知。
                  4.使用*通配符允許指定連接點必須有一個目標,但是你對它類型是什么不感興趣。
                  5.在使用handler(TypePattern)切入點的異常處理上,使用staticinitialization(TypePattern)的靜態類初始化,以及有趣地使用preinitialization(Signature)的對象初始化上,在這些地方出現的連接點不具有使用target([Type|Identifier])切入點進行展示的任何目標環境。

              以下顯示了target([Type|Identifier])的兩個示例:
              1.當目標是Identifier指定的MyClass對象時,捕獲連接點
              2.當方法調用目標的類型是Type指定的AnotherClass時,捕獲連接點


           

          package com.aspectj;

          public aspect TargetRecipe {
              
          /**
               * Specifies calling advice whenever the executing
               * object is of a type that matches the following rules:
               * 
               * Identifiers:MyClass object
               
          */

              pointcut targetIdentifierMyClassPointcut(MyClass object):target(object);
              
          /**
               * Specifies calling advice whenever the executing
               * object is of a type that matches the following rules:
               * 
               * Type Pattern:AnotherClass
               
          */
              
              pointcut targetTypePatternAnotherClassPointcut():target(AnotherClass);
              
              
          //Advice declaration
              before(MyClass object) : targetIdentifierMyClassPointcut(object) && !within(TargetRecipe+{
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by targetIdentifierMyClassPointcut()");
                  System.out.println(
          "Join Point Kind" + thisJoinPoint.getKind());
                  System.out.println(
          "this reference as passed by identifier " + object);
                  System.out.println(
          "Object referenced by this: " + thisJoinPoint.getThis());
                  System.out.println(
          "Signature: " + thisJoinPoint.getStaticPart().getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
                  System.out.println(
          "-----------------------------------------");        
              }

              
              
          //Advice declaration
              before() : targetTypePatternAnotherClassPointcut() && !within(TargetRecipe+{
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by targetTypePatternAnotherClassPointcut()");
                  System.out.println(
          "Join Point Kind" + thisJoinPoint.getKind());
                  System.out.println(
          "Type of executing object: " + thisJoinPoint.getThis().getClass().getName());
                  System.out.println(
          "Object referenced by this: " + thisJoinPoint.getThis());
                  System.out.println(
          "Signature: " + thisJoinPoint.getStaticPart().getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
                  System.out.println(
          "-----------------------------------------");        
              }


          }



          三. 捕獲何時連接點的參數是某個數字、類型和次序
              使用args([Types|Identifiers])切入點。這個切入點的語法如下:
              pointcut <pointcut name>(<any value to be picked up>):args(<types> or <identifiers> | .. | *,<repeat>);

              args([Types|Identifiers])切入點具有8個關鍵特征:
                  1.可以使用Types和Identifiers的任意組合來搜索到適當的連接點上,并把適當的環境展示給通知。
                  2.Identifier用于檢查運行時對象的類型,它們是捕捉的連接點處的參數,以及根據需要把這些對象展示給通知。
                  3.使用..允許在一定程度上靈活地選擇特定連接點處的參數數量,它們必須與args([Type|Identifier])聲明匹配。
                  4.如果不使用..,args([Type|Identifier])切入點就會選擇與指定的類型精確匹配的所有連接點。這就是說:切入點只與在運行時其參數具有相同次序、數量和類型的方法上的連接點匹配。
          如果使用..,切入點就會使用“最佳適配”策略。這意味著語句args(MyClass,..,float)將導致任何匹配的連接點都具有兩個參數,它開始于一個MyClass對象,其后接著任意數量的參數,他們中間包括一個浮點數。
                  5.在單個args([Type|Identifier])聲明中只能使用一個..。
                  6.使用*通配符允許在參數的類型方面表現處一定的靈活性,但是連接點的參數數量必須匹配。
                      例如,如果在args([Type|Identifier])切入點聲明中指定單個*,args(*),那么這個切入點將與具有一個任意類型參數的任何連接點匹配,并且會忽略沒有參數的任何連接點。類似地,語句args(*,*)將匹配包含兩個任意類型參數的任何連接點。
                  7. 出現在字段訪問中的連接點(通過get(TypePattern)切入點或set(TypePattern)切入點捕獲)或者出現在靜態類初始化中的連接點(通過staticinitialization(TypePattern)切入點捕獲)沒有要使用args([Types|Identifiers])切入點展示的任何參數。
                  8. 如果把Object用作要被args([Types|Identifiers])切入點選擇的標識符的類型,那么這將成功地匹配基本類型以及特定的Object實例。基本類型會自動“裝箱”進其對應的對象類型中,例如,在把float基本類型傳遞給通知前,會將其“裝箱”進Float中。這種行為提供了一種方法,可以通過它把基本參數值帶到通知中。

              以下顯示了args([Types|Identifiers])的兩個示例
              1.當方法的參數是Identifier指定的MyClass對象時,捕獲所有連接點
              2.當參數的類型是Type指定的AnotherClass時,捕獲連接點

          package com.aspectj;

          public aspect ArgsRecipe {
              
          /**
               * Specifies calling advice whenever the executing
               * object is of a type that matches the following rules:
               * 
               * Identifiers:MyClass object
               
          */

              pointcut argIdentifierMyClassPointcut(MyClass object):args(object);
              
          /**
               * Specifies calling advice whenever the executing
               * object is of a type that matches the following rules:
               * 
               * Type Pattern:AnotherClass
               
          */
              
              pointcut argTypePatternAnotherClassPointcut():args(AnotherClass);
              
              
          //Advice declaration
              before(MyClass object) : argIdentifierMyClassPointcut(object) && !within(ArgsRecipe+{
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by argIdentifierMyClassPointcut()");
                  System.out.println(
          "Join Point Kind" + thisJoinPoint.getKind());
                  System.out.println(
          "this reference as passed by identifier " + object);
                  System.out.println(
          "Object referenced by this: " + thisJoinPoint.getThis());
                  System.out.println(
          "Signature: " + thisJoinPoint.getStaticPart().getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
                  System.out.println(
          "-----------------------------------------");        
              }

              
              
          //Advice declaration
              before() : argTypePatternAnotherClassPointcut() && !within(ArgsRecipe+{
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by argTypePatternAnotherClassPointcut()");
                  System.out.println(
          "Join Point Kind" + thisJoinPoint.getKind());
                  System.out.println(
          "Type of executing object: " + thisJoinPoint.getThis().getClass().getName());
                  System.out.println(
          "Object referenced by this: " + thisJoinPoint.getThis());
                  System.out.println(
          "Signature: " + thisJoinPoint.getStaticPart().getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
                  System.out.println(
          "-----------------------------------------");        
              }


          }

          posted on 2008-08-25 15:11 Brian 閱讀(291) 評論(0)  編輯  收藏 所屬分類: 《AspectJ Cookbook》讀書筆記

          公告


          導航

          <2008年8月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          統計

          常用鏈接

          留言簿(4)

          隨筆分類

          隨筆檔案

          收藏夾

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 绵竹市| 平遥县| 盐山县| 玉林市| 临武县| 昂仁县| 奉化市| 和田市| 泸州市| 雷山县| 绵竹市| 治多县| 陆良县| 营山县| 蒙山县| 中牟县| 南昌市| 清河县| 宜兰市| 泽库县| 邓州市| 方正县| 阿拉善右旗| 弥勒县| 浠水县| 寿阳县| 秭归县| 台南县| 凤台县| 洛扎县| 东海县| 绥江县| 政和县| 修文县| 浑源县| 大洼县| 平度市| 舒城县| 霍山县| 洪泽县| 原平市|