AspectJ初探

早晨收到IBM developerWorks的邮件,看看有啥值得关注的东东。看到篇关于AOP的介绍,就大致读了一下,文章倒没什么新意,就是介绍AOP在项目中的应用,如何简化log机制等。

我对AOP也有些了解,主要研究过Spring中AOP实现使用的Dynamic Proxy机制,对于pointcut和advice也有些概念。但也仅此而已,没有实际写过一行AOP的代码,更不用说在项目中使用AOP了。点了点文章末尾的链接,进入了AOP的世界,看看AOP的几种不同实现,以及对其的比较文章,倒引起了我对AspectJ的兴趣。并非其它实现如AspectWerkz,JBoss4.0或Spring不如AspectJ,它们各有侧重,但我对AspectJ的静态检查和较好的IDE集成性(有eclipse3.0的插件ajdt)比较好奇。于是网上down了个ajdt(下载url:http://www.eclipse.org/ajdt/),开始了对AspectJ的探索之旅。

Ajdt的安装和其它eclipse插件完全一样,解压,拷贝到相应目录,重启eclipse就OK了。进入eclipse,发现多了个按钮,有AJ字样,点击就弹出创建AspectJ项目的窗口。先别着急,再查看window->preferences发现多了AspectJ和Visualiser栏目,随便点点,也不用做什么更改,就能确认AJDT已经成功的集成进来了。

新建个AspectJ项目,项目名就叫myaspect吧。在Package Explorer 中展开新项目,发现除了jre外它自己加入了一个AspectJ的lib,这就是AspectJ的类库了,下面是一个叫build.ajproperties的文件,肯定是配置文件了,但具体配什么我也没管太多,就希望马上能写段代码看到AOP的威力了,倒就因为这个后面郁闷好久,这是后话!

写点什么代码呢,初次使用,当然是越简单越好,但我对AspectJ的语法一窍不通啊。想到网上搜索,又觉得不系统,而且大部分文章都是讲AspectJ的好处,讲到具体使用却很少。正郁闷时看到eclipse的help菜单,想想说不定有帮助。打开help content,果然多了AspectJ Language GuideAspectJ Development User Guide目录。这其实有点出乎我的意外,eclipse插件我也装了不少,如tomcat,lomboz等,但都没有帮助文档的,看来AJDT就是考虑的周到,这也大大增加了我对AspectJ的好感,得好好研究研究!文档当然都是英文,但这可难不倒俺,当程序员的英文其它水平不行,说到“读”那却肯定没问题的。浏览了下这些help,找了篇Getting Started的Basic tutorial就跟着做了,新建项目,新建个叫Hello的类,代码很少,就是打印“Hello”。

 

1 ExpandedBlockStart.gif ContractedBlock.gif public   static   void  main(String[] args)  dot.gif {
2InBlock.gif     sayHello();
3ExpandedBlockEnd.gif}
 
4 None.gif
5 ExpandedBlockStart.gifContractedBlock.gif public   static   void  sayHello()  dot.gif {
6InBlock.gif     System.out.print("Hello");
7ExpandedBlockEnd.gif}
 

 

然后新建个aspect,叫World吧,代码也很简单,拷贝过去先:

1 ExpandedBlockStart.gif ContractedBlock.gif public  aspect World  dot.gif
2InBlock.gif     pointcut greeting() : execution(*Hello.sayHello(..)); 
3InBlock.gif
4ExpandedSubBlockStart.gifContractedSubBlock.gif     after() returning() : greeting() dot.gif
5InBlock.gif         System.out.println(" World!"); 
6ExpandedSubBlockEnd.gif     }
 
7InBlock.gif
8ExpandedBlockEnd.gif}

 

AspectJ语法我不懂,但英文还认识,pointcut就是切点的意思,这段代码估计就是在执行Hello.sayHello方法后,打印一个“World!”,但*和..是啥意思我就不大了解了。先急着看效果,我就运行Hello类了,当然我按照文档做,要run as AspectJ/Java application。运行结果:“Hello”。咋不对呢,难道我写错了?先删除代码,这次不拷贝了,自己手写。还真认识pointcut,after这些关键字,会高亮显示,边打边就报错,打全了函数就好了,这跟java的静态检查完全一样嘛。试着删除*,报错,删除..,好像没事,删除returning(),好像也没事,我这纯粹是盲人摸象嘛!呵呵,没办法,我就这性格。倒也增加了几分对了解其语法的渴望。但现在我还不看,第一次运行,连个象样的结果还没出来啊,这不是打击我积极性吗?手工输入了一遍,没错误了,运行。。。靠!还是老样子,这什么Getting Started啊,我心中暗骂。仔细在看看文档,好像也没问题啊,但它说的那个Cross References显示好像和我不一样,看来是我的问题。出师不利啊!

我可没那么容易放弃,再来一遍,反正简单,几分钟又好了,但结果还是一样。我郁闷啊!失意中我瞎点点,打开了那个property文件,还是图形化的呢。诶,好像那个World.aj没勾上,难道因为这个?仔细看看说明,included files…对了,AspectJ的特性就是需要用自己的acj编译器进行编译,这可能就是编译的类列表。勾上,保存文件,果然开始编译,运行。。。结果为:“Hello World!”成功了,哈哈,这可是俺的第一个AOP成功案例啊!兴奋中想起AspectJ要用自己的编译器编译,编译出来是.class文件,但肯定往里面加了些东西。于是到eclipse的workspace中找编译出来的class文件,双击打开(嘿嘿!俺有小颖,自动反编译),这就是经AspectJ编译后的Hello类代码,原来加了行语句。

1 None.gif      public   static   void  sayHello()
2 None.gif
3 ExpandedBlockStart.gifContractedBlock.gif     dot.gif {        System.out.print("Hello");       
                   World.aspectOf().ajc$afterReturning$helloworld_World$
1$f69f5afa();
4InBlock.gif
5ExpandedBlockEnd.gif         }

6 None.gif

World.aj也编译成了World.class,代码较长:

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

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

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

42InBlock.gif
43InBlock.gif    public static boolean hasAspect()
44InBlock.gif
45ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
46InBlock.gif
47InBlock.gif        return ajc$perSingletonInstance != null;
48InBlock.gif
49ExpandedSubBlockEnd.gif    }

50InBlock.gif
51InBlock.gif    private static void ajc$postClinit()
52InBlock.gif
53ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
54InBlock.gif
55InBlock.gif        ajc$perSingletonInstance = new World();
56InBlock.gif
57ExpandedSubBlockEnd.gif    }

58InBlock.gif
59InBlock.gif    static 
60InBlock.gif
61ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
62InBlock.gif
63InBlock.gif        try
64InBlock.gif
65ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
66InBlock.gif
67InBlock.gif            ajc$postClinit();
68InBlock.gif
69ExpandedSubBlockEnd.gif        }

70InBlock.gif
71InBlock.gif        catch(Throwable throwable)
72InBlock.gif
73ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
74InBlock.gif
75InBlock.gif            ajc$initFailureCause = throwable;
76InBlock.gif
77ExpandedSubBlockEnd.gif        }

78InBlock.gif
79ExpandedSubBlockEnd.gif    }

80InBlock.gif
81ExpandedBlockEnd.gif}

82 None.gif

研究一下:也就是生成个默认构造函数的World类,加了个ajc$afterReturning$helloworld_World$1$f69f5afa()方法,其它好像都是AspectJ生成的class必带的代码,定义了一个public static final World ajc$perSingletonInstance的类,还有一个private static Throwable ajc$initFailureCause异常,public static World aspectOf()和public static boolean hasAspect()会被自动调用。这就是AspectJ能运行的原理了,当然还有更复杂的东西,但从这个最简单的例子也能了解些端倪了。<o:p></o:p>

接下来就是学习它的语法了,其实也不难(我就奇怪网上把AspectJ的学习曲线说的多陡峭,比java难多少),也就是pointcut和advice,各自有各自的一些关键字。我也对开始瞎试,有的报错,有的不报错的原因有了理论的认识了。<o:p></o:p>

整个探索的时间也不长,1个小时左右,比我写这篇东西少多了,呵呵!打字打的累啊,回去打星际去!看哪天有空,接着研究,也一定写篇文章,估计也还有人看的,呵呵!<o:p></o:p>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值