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

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

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

    邊城愚人

    如果我不在邊城,我一定是在前往邊城的路上。

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      31 隨筆 :: 0 文章 :: 96 評論 :: 0 Trackbacks

    ??? ??? 讓我好好想想, AspectJ 中最常用的切入點是什么?哦,也許是 call Method-Signature )吧。這是個相對簡單的方法簽名。實際上,方法簽名的完整形式如下:

    [modifiers] [returnTypePattern] [DeclaredTypePattern.]methodName([Parameters])[throws TypePattern] ,其中方括號中的簽名組件是可選的。 modifiers 為修飾符模式, returnTypePattern 為返回類型模式, DeclaredTypePattern 為類型聲明模式, methodName 為方法名稱, Parameters 為方法參數, throws TypePattern throw 字句。該文僅僅介紹 DeclaredTypePattern ,因為相比之下其它模式比較簡單的多。

    ??? ??? 在介紹類型聲明模式之前,介紹一下類型模式。類型模式是匹配一種類型或一系列類型的方法。精確的類型模式是如 java.lang.String 一樣的完整的有效類型名。但在使用 AspectJ 類型模式時,經常會用到下列通配符(這些通配符同樣適用于 Spring AOP )。

    1 )“ *” :代表任意字符的零次或多次出現。當嵌入到一串字符的內部時,它匹配任意字符的零次或多次出現,除了包分割符( . )。

    2 )“ +” :用作類型模式的后綴,代表此類型和其所有的子類型(那些擴展或實現帶后綴類型的類型)。

    3 )“ ..” :用于指定所有的子包,它匹配任意以包分割符開頭和結束的字符串。
    ?

    下面給出幾個示例:

    1 *Account 使用 Account 名稱結束的類型,如 CheckingAccount
    2
    java.*.Date 類型 Date 在任何直接的 java 子包中,如 java.util.Date java.sql.Date
    3
    java..* 任何在 java 包或者所有子包中的類型,如 java.awt 或者 java.awt.event
    4
    javax..*Model+ 所有 javax 包或者子包中以 Model 結尾的類型和其所有子類,如 TableModel,TreeModel

    ??? ??? 現在開始說說類型聲明模式。實際上,在方法簽名中,類型聲明模式不是必需的(就像很多書中所說,應該少用類型聲明模式而改用與“ target” 結合的切入點指示符)。但如果指定了類型聲明模式,切入點將只匹配對由模式匹配的類型(或者超類型)聲明的方法的調用。和其他類型模式一樣,類型聲明模式支持上述的通配符。同時,它也支持復合類型模式。對于類型聲明模式來說,程序員容易犯錯的地方在于類型聲明模式是基于靜態類型而不是運行時類型,這也是本文的主要內容。

    ? ??

    在很好地理解類型聲明模式之前,先看一下下面的例子:

    public ? class ?A??{
    ????
    public ? void ?foo(){
    ????????System.out.println(
    " A.foo() " );
    ????}
    }
    public ? class ?B? extends ?A{
    ????
    public ? void ?foo(){
    ????????System.out.println(
    " B.foo() " );
    ????}
    }
    public ? class ?Main?{

    ????
    ????
    public ? static ? void ?main(String[]?args)?{
    ????????A?b?
    = ? new ?B();
    ????????b.foo();?
    // (1)
    ????????callFoo(b); // (2)
    ????}

    ????
    public ? static ? void ?callFoo(A?a){
    ????????System.out.println(
    " Call?A " );
    ????}
    ????
    ????
    public ? static ? void ?callFoo(B?b){
    ????????System.out.println(
    " Call?B " );
    ????}
    }

    ??? ??? 它的運行結果是這樣的:
    ??? ??? B.foo()

    ??? ??? Call A

    ??? ??? 和你的想法一致嗎?對于( 1 )處 b.foo() 的調用應用了面向對象中的覆蓋( override ),它是動態的,是在運行時進行解析。而( 2 )處的 callFoo (b) 則是重載( overload ),它是靜態的,是在編譯時解析的。因此,對于變量 b ,雖然它是 B 的一個實例,但 b 的靜態類型(也就是變量聲明的類型)是 A ;由于重載方法的選擇是靜態的,所以 main 中調用的是 callFoo(A a) ,而不是 callFoo(B b)

    ??? ??? 終于說到了類型聲明模式。類型聲明模式是基于靜態類型信息進行匹配的,而不是動態(或者運行時。下面根據幾個典型的例子說明類型聲明模式的特性。

    ??? ??? 還是上面的兩個類 A B ,現在我們定義一個方面如下:


    public ?aspect?TypeAspect?{

    ????????pointcut?callA():
    ????????????call(
    * ?A. * (..));
    ????????
    ????????before():callA(){
    ????????????System.out.println(
    " call?A " );
    ????????}????
    }

    ??? ??? main 函數內容如下:


    public ? static ? void ?main(String[]?args)?{
    ????????A?b1?
    = ? new ?B();
    ????????b1.foo();
    ????????
    ????????B?b2?
    = ? new ?B();
    ????????b2.foo();
    ????}

    ??? ??

    運行結果如下:

    call A

    B.foo()

    call A

    B.foo()

    ??? ??? 可以看到,盡管切入點 callA() 聲明的類型為 A ,但實際上,切入點 callA() 可以捕獲 A 中的方法及其子類中繼承于 A 的方法或重載 A 的方法,而聲明的靜態類型既可以是 A 也可以是其子類。

    ??? ??? 但如果在 B 中增加一個新的方法:

    public ? void ?doAnotherThing(){

    System.out.println(
    " B.doAnotherThing " );

    }

    ??? ??? main 函數改為:

    public ? static ? void ?main(String[]?args)?{

    B?b2?
    = ? new ?B();

    b2.doAnotherThing();

    }

    ?? ??? 輸出結果為: B.doAnotherThing ,如果想對 A 的子類 B 中擴展的方法進行通知,可采用的方法是將切入點 callA() 改為 pointcut callA(): call (* A+.*(..));

    ??? ??? 讓我們再來看另一種情景:如果定義一個切入點如下:


    ?pointcut?callB():call( * ?B. * (..));

    before():callB(){

    System.out.println(
    " call?B " );

    }

    ??? ??? main 函數內容如下:


    public ? static ? void ?main(String[]?args)?{

    A?b?
    = ? new ?B();

    b.foo();

    }

    ??? ??? 運行結果為: B.foo() b.foo() 沒有匹配切入點 callB() 的原因在于, b 的靜態類型是 A ,從靜態類型的角度來看,這是對 A 的調用,而不是對 B 的調用。在使用 AspectJ 的類型聲明時,很容易在這個地方犯錯。

    ??? ??? 好了,如上便是有關類型聲明模式的東西,說得有些凌亂,希望對 AspectJ 初學者有些幫助(我本身也是個初學者)。該文參考了《 Eclipse AspectJ 》和《 AspectJ cookbook 》。


    posted on 2007-07-07 14:54 kafka0102 閱讀(1748) 評論(2)  編輯  收藏 所屬分類: AOP

    評論

    # re: AspectJ學習(1)理解方法簽名中的類型聲明模式 2007-07-08 22:37 go
    good...  回復  更多評論
      

    # re: AspectJ學習(1)理解方法簽名中的類型聲明模式[未登錄] 2013-01-08 11:21 cj
    good,頂頂  回復  更多評論
      

    主站蜘蛛池模板: 99在线免费观看| 在线免费观看污网站| 亚洲国产成人久久综合一区| 91免费精品国自产拍在线不卡| 亚洲AV成人无码网天堂| 亚洲宅男天堂在线观看无病毒| 最近中文字幕电影大全免费版| 亚洲色欲色欱wwW在线| 中文字幕亚洲日本岛国片| 亚欧在线精品免费观看一区| 美女露100%胸无遮挡免费观看| 亚洲Av永久无码精品三区在线| 成人免费看黄20分钟| 十八禁视频在线观看免费无码无遮挡骂过 | 国产精品免费在线播放| 亚洲精品在线播放视频| 亚洲AV网站在线观看| 免费观看激色视频网站bd| 国产免费牲交视频免费播放| 国产成人精品亚洲日本在线| 亚洲伊人久久大香线蕉综合图片| 亚洲人成网站免费播放| 久草免费福利视频| 在线观看亚洲精品专区| 亚洲中文久久精品无码1| 亚洲日产无码中文字幕| 日本免费一区二区三区最新vr| 日韩免费在线观看视频| 色爽黄1000部免费软件下载| 亚洲日本乱码卡2卡3卡新区| 亚洲精品无码AV人在线播放| 国产在线a不卡免费视频| 最近中文字幕完整免费视频ww| 一级一级毛片免费播放| 亚洲色成人四虎在线观看| 91亚洲精品视频| 亚洲爆乳精品无码一区二区三区 | 亚洲综合免费视频| 亚洲色欲色欲www在线丝| 又黄又爽一线毛片免费观看| 无码中文在线二区免费|