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

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

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


    隨筆-35  評(píng)論-97  文章-0  trackbacks-0

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

    1. AspectJ是一個(gè)代碼生成工具(Code Generator)。
    2. AspectJ語(yǔ)法就是用來(lái)定義代碼生成規(guī)則的語(yǔ)法。您如果使用過(guò)Java Compiler Compiler (JavaCC),您會(huì)發(fā)現(xiàn),兩者的代碼生成規(guī)則的理念驚人相似。
    3. AspectJ有自己的語(yǔ)法編譯工具,編譯的結(jié)果是Java Class文件,運(yùn)行的時(shí)候,classpath需要包含AspectJ的一個(gè)jar文件(Runtime lib)。
    4. ....

    看了上面幾點(diǎn),我就想看看它怎么把代碼生成了。現(xiàn)在做一個(gè)試驗(yàn)。

    一個(gè)類(lèi)(包括main函數(shù)):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();
        }

    }

     

    一個(gè)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!");
        }

    }

    以上都是源碼部分哦。

    運(yùn)行結(jié)果:

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

    說(shuō)明程序是正常運(yùn)作的哦。

    好了,下面,做三個(gè)操作:

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

          說(shuō)明:可以使用ajdt的eclipse插件帶的導(dǎo)出功能,Export -->  JAR file with ApectJ support

    2、新建一個(gè)AspectJ工程,將apectjtest.jar加入類(lèi)路徑,使用jad來(lái)反編譯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、運(yùn)行一下Speaker.class

    得到結(jié)果:

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

     

    呵呵,結(jié)果跟源碼運(yùn)行是一樣的哦(不一樣就是你的人品問(wèn)題咯!!)

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

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

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

        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();//多了這行
        }

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

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

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

    回來(lái)看看AspectObserver.class的反編譯代碼,哈哈,這就對(duì)了,aspectOf返回的是AspectObserver的一個(gè)實(shí)例,返回實(shí)例在調(diào)用實(shí)例方法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();

    是怎么一回事啦。

    這正是應(yīng)了上面所提的兩點(diǎn):

    1. AspectJ是一個(gè)代碼生成工具(Code Generator)。
    2. AspectJ語(yǔ)法就是用來(lái)定義代碼生成規(guī)則的語(yǔ)法。

    用這兩點(diǎn)去感受apectj在程序里該如何去運(yùn)用使用,就清晰多啦!

    posted on 2007-07-12 01:12 三告習(xí)習(xí) 閱讀(5195) 評(píng)論(6)  編輯  收藏 所屬分類(lèi): AOP

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

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 久久久久久久99精品免费| 激情吃奶吻胸免费视频xxxx| 久久亚洲精品国产精品婷婷| 亚洲成AV人片高潮喷水| 午夜成人无码福利免费视频| 成全视频在线观看免费| 最近2022中文字幕免费视频| 毛片大全免费观看| 亚洲AⅤ永久无码精品AA | 无码精品A∨在线观看免费| 毛片免费在线观看网站| 亚洲Av无码乱码在线znlu| 国产亚洲一区二区三区在线| 亚洲神级电影国语版| 色窝窝亚洲av网| a级成人免费毛片完整版| 日韩精品免费一级视频| 日韩视频在线免费| 国产亚洲美女精品久久久2020| 亚洲视频一区在线播放| 自拍偷自拍亚洲精品偷一| 水蜜桃视频在线观看免费播放高清| 1000部国产成人免费视频| 国产一区二区三区在线免费| 亚洲国产精品无码一线岛国| 久久精品国产亚洲av麻豆蜜芽| 一级一看免费完整版毛片| xxxxx免费视频| 国产免费观看网站| 亚洲AV一宅男色影视| 国产亚洲欧美日韩亚洲中文色| 最近免费mv在线观看动漫| 日韩在线a视频免费播放| 久久精品国产精品亚洲色婷婷| 亚洲人成色777777老人头| 黄色网站软件app在线观看免费| 好先生在线观看免费播放| 亚洲精品美女久久久久99| 亚洲精品美女久久久久久久| 老司机精品免费视频| 成年男女免费视频网站|