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

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

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


    隨筆-35  評論-97  文章-0  trackbacks-0

    http://www.ibm.com/developerworks/cn/java/l-aspectJ/index.html中介紹了What is AspectJ 。

    1. AspectJ是一個代碼生成工具(Code Generator)。
    2. AspectJ語法就是用來定義代碼生成規則的語法。您如果使用過Java Compiler Compiler (JavaCC),您會發現,兩者的代碼生成規則的理念驚人相似。
    3. AspectJ有自己的語法編譯工具,編譯的結果是Java Class文件,運行的時候,classpath需要包含AspectJ的一個jar文件(Runtime lib)。
    4. ....

    看了上面幾點,我就想看看它怎么把代碼生成了?,F在做一個試驗。

    一個類(包括main函數):Speaker.java

    package test.aspectj;

    public class Speaker
    {
        
    public void speak()
        
    {
            System.out.println(
    "[Speaker] bla bla ");
        }


        
    public static void main(String[] args)
        
    {
            Speaker speaker 
    = new Speaker();
            speaker.speak();
        }

    }

     

    一個aspect:AspectObserver.aj

    package test.aspectj;

    public aspect AspectObserver
    {
        pointcut speakerSpeak():
            call(
    void *Speaker.speak());
        before() : speakerSpeak() 
    {
            System.out.println(
    "[AspectObserver] speaker is about to speak!");
        }

        after() returning() : speakerSpeak() 
    {
            System.out.println(
    "[AspectObserver] speaker has completed his speech!");
        }

    }

    以上都是源碼部分哦。

    運行結果:

    [AspectObserver] speaker is about to speak!
    [Speaker] bla bla 
    [AspectObserver] speaker has completed his speech
    !

    說明程序是正常運作的哦。

    好了,下面,做三個操作:

    1、將以上的編譯成的class文件打包成apectjtest.jar文件。

          說明:可以使用ajdt的eclipse插件帶的導出功能,Export -->  JAR file with ApectJ support

    2、新建一個AspectJ工程,將apectjtest.jar加入類路徑,使用jad來反編譯Speaker.class和AspectObserver.class

     得到反編譯后的源碼:

    Speaker.class

    /*jadclipse*/// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
    // Jad home page: http://www.kpdus.com/jad.html
    // Decompiler options: packimports(3) radix(10) lradix(10) 
    // Source File Name:   Speaker.java

    package test.aspectj;

    import java.io.PrintStream;

    // Referenced classes of package test.aspectj:
    //            AspectObserver

    public class Speaker
    {

        
    public Speaker()
        
    {
        }


        
    public void speak()
        
    {
            System.out.println(
    "[Speaker] bla bla ");
        }


        
    public static void main(String args[])
        
    {
            Speaker speaker 
    = new Speaker();
            AspectObserver.aspectOf().ajc$before$test_aspectj_AspectObserver$
    1$b2b6354();
            speaker.speak();
            AspectObserver.aspectOf().ajc$afterReturning$test_aspectj_AspectObserver$
    2$b2b6354();
        }

    }

     

    AspectObserver.class

    /*jadclipse*/// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
    // Jad home page: http://www.kpdus.com/jad.html
    // Decompiler options: packimports(3) radix(10) lradix(10) 
    // Source File Name:   AspectObserver.aj

    package test.aspectj;

    import java.io.PrintStream;
    import org.aspectj.lang.NoAspectBoundException;

    public class AspectObserver
    {

        
    public AspectObserver()
        
    {
        }


        
    void ajc$pointcut$$speakerSpeak$44()
        
    {
        }


        
    public void ajc$before$test_aspectj_AspectObserver$1$b2b6354()
        
    {
            System.out.println(
    "[AspectObserver] speaker is about to speak!");
        }


        
    public void ajc$afterReturning$test_aspectj_AspectObserver$2$b2b6354()
        
    {
            System.out.println(
    "[AspectObserver] speaker has completed his speech!");
        }


        
    public static AspectObserver aspectOf()
        
    {
            
    if(ajc$perSingletonInstance == null)
                
    throw new NoAspectBoundException("test_aspectj_AspectObserver", ajc$initFailureCause);
            
    else
                
    return ajc$perSingletonInstance;
        }


        
    public static boolean hasAspect()
        
    {
            
    return ajc$perSingletonInstance != null;
        }


        
    private static void ajc$postClinit()
        
    {
            ajc$perSingletonInstance 
    = new AspectObserver();
        }


        
    private static Throwable ajc$initFailureCause;
        
    public static final AspectObserver ajc$perSingletonInstance;

        
    static 
        
    {
            
    try
            
    {
                ajc$postClinit();
            }

            
    catch(Throwable throwable)
            
    {
                ajc$initFailureCause 
    = throwable;
            }

        }

    }

    3、運行一下Speaker.class

    得到結果:

    [AspectObserver] speaker is about to speak!
    [Speaker] bla bla 
    [AspectObserver] speaker has completed his speech
    !

     

    呵呵,結果跟源碼運行是一樣的哦(不一樣就是你的人品問題咯?。。?/p>

    分析一下,先理解AspectJ編譯器為我們做了什么事情:

    首先、AspectJ從文件列表里取出所有的文件名,然后讀取這些文件,進行分析。 
    二、AspectJ發現一些文件含有aspect的定義,在這個例子里,就是AspectObserver的定義;這些aspect就是代碼生成規則。 
    三、AspectJ根據這些aspect代碼生成規則,修改添加你的源代碼。在這個例子里,源碼是修改成怎樣了?比較一下反編譯后的代碼和源碼便知。 
    四、AspectJ讀取AspectObserver的定義,發現了一個pointcut
    --speakerSpeak();這個pointcut的定義是call(void *Speaker.speak()),表示所有對Speaker類的speak方法的執行點。 
    五、AspectJ繼續讀取AspectObserver的定義,發現了一個before(),這在AspectJ中叫做Advice。Advice允許你在某個類的方法的調用之前或調用之后,加入另外的代碼。加入的代碼是什么?比較一下反編譯后的代碼和源碼吧。 AspectJ繼續讀取AspectObserver的定義.

    好了,回頭看看反編譯后的Speaker.class,與源碼Speaker.java差別在哪呢?主要在main函數中,方法被調用的前后

        public static void main(String args[])
        
    {
            Speaker speaker 
    = new Speaker();
            AspectObserver.aspectOf().ajc$before$test_aspectj_AspectObserver$
    1$b2b6354();//多了這行
            speaker.speak();
            AspectObserver.aspectOf().ajc$afterReturning$test_aspectj_AspectObserver$
    2$b2b6354();//多了這行
        }

    不同的地方就是多出了兩行,雖然有$和數字,但是很容易看出,這同我們平常寫的java代碼差不了多少。

            AspectObserver.aspectOf().ajc$before$test_aspectj_AspectObserver$1$b2b6354();

    這行代碼中,看起來不就是AspectObserver類調用了靜態方法aspectOf()嗎,接著aspectOf()的返回對象又調用ajc$before$test_aspectj_AspectObserver$1$b2b6354()方法嗎?

    回來看看AspectObserver.class的反編譯代碼,哈哈,這就對了,aspectOf返回的是AspectObserver的一個實例,返回實例在調用實例方法ajc$before$test_aspectj_AspectObserver$1$b2b6354()。ajc$before$test_aspectj_AspectObserver$1$b2b6354()是干什么的呢?呵呵,不正是我們要的攔截方法所要做的操作嗎?

    System.out.println("[AspectObserver] speaker is about to speak!");

    同樣,可知

     AspectObserver.aspectOf().ajc$afterReturning$test_aspectj_AspectObserver$2$b2b6354();

    是怎么一回事啦。

    這正是應了上面所提的兩點:

    1. AspectJ是一個代碼生成工具(Code Generator)。
    2. AspectJ語法就是用來定義代碼生成規則的語法。

    用這兩點去感受apectj在程序里該如何去運用使用,就清晰多啦!

    posted on 2007-07-12 01:12 三告習習 閱讀(5194) 評論(6)  編輯  收藏 所屬分類: AOP

    評論:
    # re: [AspectJ] 明明白白AspectJ (1) 2007-07-12 21:21 | ehe
    學習  回復  更多評論
      
    # re: [AspectJ] 明明白白AspectJ (1) 2007-07-19 21:02 | Danfo
    能不能講講spring代理實現aspectJ的機制呢?  回復  更多評論
      
    # re: [AspectJ] 明明白白AspectJ (1) 2007-07-19 21:40 | 三告習習
    @Danfo
    唉呀呀...苦惱時間少啊 :(
    快啦快啦  回復  更多評論
      
    # re: [AspectJ] 明明白白AspectJ (1) 2007-07-22 14:56 | 不長樹的葉子
    還是不知道  回復  更多評論
      
    # re: [AspectJ] 明明白白AspectJ (1) 2008-06-28 20:05 | moliqin
    鑒定完畢  回復  更多評論
      
    # re: [AspectJ] 明明白白AspectJ (1) 2012-07-02 11:55 | Hongxu Chen
    想問一下如果是用annotation語法生成的aspect和這里的方法在字節碼上有什么差異嗎?  回復  更多評論
      

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 五月婷婷在线免费观看| 日本高清色本免费现在观看| 亚洲校园春色小说| 全免费a级毛片免费看无码| 青青青视频免费观看| 亚洲VA中文字幕不卡无码| 在线视频精品免费| 一本一道dvd在线观看免费视频| 亚洲国产成人久久综合碰碰动漫3d| 免费无码A片一区二三区| 国产精品美女久久久免费| 亚洲国产日产无码精品| 亚洲成A人片在线观看中文| 少妇无码一区二区三区免费| 亚洲风情亚Aⅴ在线发布| 亚洲av永久无码制服河南实里| 99视频在线精品免费观看6| 99久久99这里只有免费的精品| 亚洲高清一区二区三区| 亚洲男人的天堂www| 成年女人18级毛片毛片免费 | 久久久久久亚洲精品| 拨牐拨牐x8免费| 免费视频精品一区二区三区 | 亚洲av无码电影网| 亚洲综合无码AV一区二区| 最近中文字幕无吗免费高清| 水蜜桃视频在线观看免费播放高清 | 九九免费精品视频在这里| 亚洲av乱码一区二区三区香蕉| 国产a v无码专区亚洲av| 成人免费视频一区二区三区| 日韩精品久久久久久免费| 一级做a爰片久久毛片免费陪 | 亚洲国产精品成人精品软件| 在线观看亚洲精品福利片| 日本免费一区二区三区最新| 在线永久免费的视频草莓| 日韩免费无码一区二区三区 | 无人在线直播免费观看| 国产高清不卡免费视频|