AspectJ初探

          早晨收到IBM developerWorks的郵件,看看有啥值得關(guān)注的東東。看到篇關(guān)于AOP的介紹,就大致讀了一下,文章倒沒(méi)什么新意,就是介紹AOP在項(xiàng)目中的應(yīng)用,如何簡(jiǎn)化log機(jī)制等。

          我對(duì)AOP也有些了解,主要研究過(guò)Spring中AOP實(shí)現(xiàn)使用的Dynamic Proxy機(jī)制,對(duì)于pointcut和advice也有些概念。但也僅此而已,沒(méi)有實(shí)際寫(xiě)過(guò)一行AOP的代碼,更不用說(shuō)在項(xiàng)目中使用AOP了。點(diǎn)了點(diǎn)文章末尾的鏈接,進(jìn)入了AOP的世界,看看AOP的幾種不同實(shí)現(xiàn),以及對(duì)其的比較文章,倒引起了我對(duì)AspectJ的興趣。并非其它實(shí)現(xiàn)如AspectWerkz,JBoss4.0或Spring不如AspectJ,它們各有側(cè)重,但我對(duì)AspectJ的靜態(tài)檢查和較好的IDE集成性(有eclipse3.0的插件ajdt)比較好奇。于是網(wǎng)上down了個(gè)ajdt(下載url:http://www.eclipse.org/ajdt/),開(kāi)始了對(duì)AspectJ的探索之旅。

          Ajdt的安裝和其它eclipse插件完全一樣,解壓,拷貝到相應(yīng)目錄,重啟eclipse就OK了。進(jìn)入eclipse,發(fā)現(xiàn)多了個(gè)按鈕,有AJ字樣,點(diǎn)擊就彈出創(chuàng)建AspectJ項(xiàng)目的窗口。先別著急,再查看window->preferences發(fā)現(xiàn)多了AspectJ和Visualiser欄目,隨便點(diǎn)點(diǎn),也不用做什么更改,就能確認(rèn)AJDT已經(jīng)成功的集成進(jìn)來(lái)了。

          新建個(gè)AspectJ項(xiàng)目,項(xiàng)目名就叫myaspect吧。在Package Explorer 中展開(kāi)新項(xiàng)目,發(fā)現(xiàn)除了jre外它自己加入了一個(gè)AspectJ的lib,這就是AspectJ的類(lèi)庫(kù)了,下面是一個(gè)叫build.ajproperties的文件,肯定是配置文件了,但具體配什么我也沒(méi)管太多,就希望馬上能寫(xiě)段代碼看到AOP的威力了,倒就因?yàn)檫@個(gè)后面郁悶好久,這是后話!

          寫(xiě)點(diǎn)什么代碼呢,初次使用,當(dāng)然是越簡(jiǎn)單越好,但我對(duì)AspectJ的語(yǔ)法一竅不通啊。想到網(wǎng)上搜索,又覺(jué)得不系統(tǒng),而且大部分文章都是講AspectJ的好處,講到具體使用卻很少。正郁悶時(shí)看到eclipse的help菜單,想想說(shuō)不定有幫助。打開(kāi)help content,果然多了AspectJ Language GuideAspectJ Development User Guide目錄。這其實(shí)有點(diǎn)出乎我的意外,eclipse插件我也裝了不少,如tomcat,lomboz等,但都沒(méi)有幫助文檔的,看來(lái)AJDT就是考慮的周到,這也大大增加了我對(duì)AspectJ的好感,得好好研究研究!文檔當(dāng)然都是英文,但這可難不倒俺,當(dāng)程序員的英文其它水平不行,說(shuō)到“讀”那卻肯定沒(méi)問(wèn)題的。瀏覽了下這些help,找了篇Getting Started的Basic tutorial就跟著做了,新建項(xiàng)目,新建個(gè)叫Hello的類(lèi),代碼很少,就是打印“Hello”。

           

          1public static void main(String[] args) {
          2     sayHello();
          3}
           
          4
          5public static void sayHello() {
          6     System.out.print("Hello");
          7}
           

           

          然后新建個(gè)aspect,叫World吧,代碼也很簡(jiǎn)單,拷貝過(guò)去先:

          1public aspect World 
          2     pointcut greeting() : execution(*Hello.sayHello(..)); 
          3
          4     after() returning() : greeting() 
          5         System.out.println(" World!"); 
          6     }
           
          7
          8}

           

          AspectJ語(yǔ)法我不懂,但英文還認(rèn)識(shí),pointcut就是切點(diǎn)的意思,這段代碼估計(jì)就是在執(zhí)行Hello.sayHello方法后,打印一個(gè)“World!”,但*和..是啥意思我就不大了解了。先急著看效果,我就運(yùn)行Hello類(lèi)了,當(dāng)然我按照文檔做,要run as AspectJ/Java application。運(yùn)行結(jié)果:“Hello”。咋不對(duì)呢,難道我寫(xiě)錯(cuò)了?先刪除代碼,這次不拷貝了,自己手寫(xiě)。還真認(rèn)識(shí)pointcut,after這些關(guān)鍵字,會(huì)高亮顯示,邊打邊就報(bào)錯(cuò),打全了函數(shù)就好了,這跟java的靜態(tài)檢查完全一樣嘛。試著刪除*,報(bào)錯(cuò),刪除..,好像沒(méi)事,刪除returning(),好像也沒(méi)事,我這純粹是盲人摸象嘛!呵呵,沒(méi)辦法,我就這性格。倒也增加了幾分對(duì)了解其語(yǔ)法的渴望。但現(xiàn)在我還不看,第一次運(yùn)行,連個(gè)象樣的結(jié)果還沒(méi)出來(lái)啊,這不是打擊我積極性嗎?手工輸入了一遍,沒(méi)錯(cuò)誤了,運(yùn)行。。??浚∵€是老樣子,這什么Getting Started啊,我心中暗罵。仔細(xì)在看看文檔,好像也沒(méi)問(wèn)題啊,但它說(shuō)的那個(gè)Cross References顯示好像和我不一樣,看來(lái)是我的問(wèn)題。出師不利?。?/FONT>

          我可沒(méi)那么容易放棄,再來(lái)一遍,反正簡(jiǎn)單,幾分鐘又好了,但結(jié)果還是一樣。我郁悶??!失意中我瞎點(diǎn)點(diǎn),打開(kāi)了那個(gè)property文件,還是圖形化的呢。誒,好像那個(gè)World.aj沒(méi)勾上,難道因?yàn)檫@個(gè)?仔細(xì)看看說(shuō)明,included files…對(duì)了,AspectJ的特性就是需要用自己的acj編譯器進(jìn)行編譯,這可能就是編譯的類(lèi)列表。勾上,保存文件,果然開(kāi)始編譯,運(yùn)行。。。結(jié)果為:“Hello World!”成功了,哈哈,這可是俺的第一個(gè)AOP成功案例??!興奮中想起AspectJ要用自己的編譯器編譯,編譯出來(lái)是.class文件,但肯定往里面加了些東西。于是到eclipse的workspace中找編譯出來(lái)的class文件,雙擊打開(kāi)(嘿嘿!俺有小穎,自動(dòng)反編譯),這就是經(jīng)AspectJ編譯后的Hello類(lèi)代碼,原來(lái)加了行語(yǔ)句。

          1    public static void sayHello()
          2
          3    {        System.out.print("Hello");       
                             World.aspectOf().ajc$afterReturning$helloworld_World$
          1$f69f5afa();
          4
          5         }

          6

          World.aj也編譯成了World.class,代碼較長(zhǎng):

           1package helloworld;
           2
           3import java.io.PrintStream;
           4
           5import org.aspectj.lang.NoAspectBoundException;
           6
           7public class World
           8
           9{
          10
          11    private static Throwable ajc$initFailureCause;
          12
          13    public static final World ajc$perSingletonInstance;
          14
          15    public World()
          16
          17    {
          18
          19    }

          20
          21    public void ajc$afterReturning$helloworld_World$1$f69f5afa()
          22
          23    {
          24
          25        System.out.println("World!");
          26
          27    }

          28
          29    public static World aspectOf()
          30
          31    {
          32
          33        if(ajc$perSingletonInstance == null)
          34
          35            throw new NoAspectBoundException("helloworld_World", ajc$initFailureCause);
          36
          37        else
          38
          39            return ajc$perSingletonInstance;
          40
          41    }

          42
          43    public static boolean hasAspect()
          44
          45    {
          46
          47        return ajc$perSingletonInstance != null;
          48
          49    }

          50
          51    private static void ajc$postClinit()
          52
          53    {
          54
          55        ajc$perSingletonInstance = new World();
          56
          57    }

          58
          59    static 
          60
          61    {
          62
          63        try
          64
          65        {
          66
          67            ajc$postClinit();
          68
          69        }

          70
          71        catch(Throwable throwable)
          72
          73        {
          74
          75            ajc$initFailureCause = throwable;
          76
          77        }

          78
          79    }

          80
          81}

          82

          研究一下:也就是生成個(gè)默認(rèn)構(gòu)造函數(shù)的World類(lèi),加了個(gè)ajc$afterReturning$helloworld_World$1$f69f5afa()方法,其它好像都是AspectJ生成的class必帶的代碼,定義了一個(gè)public static final World ajc$perSingletonInstance的類(lèi),還有一個(gè)private static Throwable ajc$initFailureCause異常,public static World aspectOf()和public static boolean hasAspect()會(huì)被自動(dòng)調(diào)用。這就是AspectJ能運(yùn)行的原理了,當(dāng)然還有更復(fù)雜的東西,但從這個(gè)最簡(jiǎn)單的例子也能了解些端倪了。

          接下來(lái)就是學(xué)習(xí)它的語(yǔ)法了,其實(shí)也不難(我就奇怪網(wǎng)上把AspectJ的學(xué)習(xí)曲線說(shuō)的多陡峭,比java難多少),也就是pointcut和advice,各自有各自的一些關(guān)鍵字。我也對(duì)開(kāi)始瞎試,有的報(bào)錯(cuò),有的不報(bào)錯(cuò)的原因有了理論的認(rèn)識(shí)了。

          整個(gè)探索的時(shí)間也不長(zhǎng),1個(gè)小時(shí)左右,比我寫(xiě)這篇東西少多了,呵呵!打字打的累啊,回去打星際去!看哪天有空,接著研究,也一定寫(xiě)篇文章,估計(jì)也還有人看的,呵呵!

          posted on 2005-08-03 19:00 pesome 閱讀(4500) 評(píng)論(4)  編輯  收藏 所屬分類(lèi): AOP

          評(píng)論

          # re: AspectJ初探 2006-12-14 18:03 Brian Sun

          你用的自動(dòng)反編譯工具是什么?呵呵,也想搞個(gè)玩玩。
            回復(fù)  更多評(píng)論   

          # re: AspectJ初探 2006-12-15 09:34 pesome

          以前用小穎,現(xiàn)在用jad  回復(fù)  更多評(píng)論   

          # re: AspectJ初探 2008-09-01 17:44 yyyfff43

          強(qiáng)文兒,頂
          aspectj確實(shí)不錯(cuò)  回復(fù)  更多評(píng)論   

          # re: AspectJ初探[未登錄](méi) 2011-10-26 21:01 beansoft

          拜讀下!  回復(fù)  更多評(píng)論   


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


          網(wǎng)站導(dǎo)航:
          相關(guān)文章:
           
          <2011年10月>
          2526272829301
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          導(dǎo)航

          統(tǒng)計(jì)

          • 隨筆 - 45
          • 文章 - 1
          • 評(píng)論 - 177
          • 引用 - 0

          公告

          主要記錄作者在學(xué)習(xí)java中的每一步足跡。除非特別說(shuō)明,所有文章均為本blog作者原創(chuàng),如需轉(zhuǎn)載請(qǐng)注明出處和原作者,如用于商業(yè)目的,需跟作者本人聯(lián)系。
          歡迎大家訪問(wèn):

          常用鏈接

          留言簿(16)

          隨筆分類(lèi)

          隨筆檔案

          文章分類(lèi)

          文章檔案

          相冊(cè)

          收藏夾

          java技術(shù)

          人間百態(tài)

          朋友們的blog

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 兴隆县| 晋城| 汶上县| 双流县| 肇源县| 阳西县| 天津市| 高邮市| 菏泽市| 浪卡子县| 黄大仙区| 南康市| 鸡东县| 石台县| 依安县| 榆社县| 蓬安县| 宁陵县| 辉南县| 元朗区| 仁化县| 阳信县| 渝北区| 凤城市| 乐至县| 沈阳市| 双柏县| 铁力市| 绥阳县| 锡林郭勒盟| 阜南县| 赫章县| 任丘市| 海城市| 嘉祥县| 万安县| 卫辉市| 颍上县| 济源市| 新昌县| 枣强县|