AOP 工具比较Word格式文档下载.docx
《AOP 工具比较Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《AOP 工具比较Word格式文档下载.docx(16页珍藏版)》请在冰豆网上搜索。
表1显示了上列出的目前可以使用的AOP工具(请参阅参考资料)。
每个工具的用户列表贴子数量可以表明它的用户基数(省略了贴子的实际数量,因为单独一个月的统计可能给读者造成误解)。
表1.在2004年11月AOP工具用户列表中的贴子数量
关于这个系列
系列面对的是在面向方面编程上有些基础,同时想扩展或加深这方面了解的开发人员。
同developerWorks的大多数文章一样,这个系列非常实用:
读完每篇介绍新技术的文章,都可以立即将其投入使用。
为这个系列选择的每个作者都是面向方面编程领域的领导或专家。
许多作者都是系列文章中介绍的项目和工具的参与者。
每篇文章都力图提供一个中立的评述,以确保这里表达的观点的公正与正确。
请就文章的评论或问题分别与这些文章的作者联系。
要对这个系列整体进行评论,可以与这个系列的负责人
NicholasLesiecki
联系。
关于本文
本文并不想突出某一个工具,而是要用一种批判的、没有偏见的方式突出每个工具的优势与不足。
虽然作者是AspectJ项目的参与者之一,但是在编写本文的时候,也咨询了其他AOP工具项目的领导人,以确保公平地展示所讨论的技术。
请注意Spring的AOP部分没有形成一个独立的下载或用户社团,所以用户基数相当比例的用户可能没有给SpringAOP发贴,而是投在别的主题上了。
在上还列出了4个额外的工具,但是它们要么缺乏用户讨论论坛,要么在11月没有贴子。
AOP工具虽然没有列在表中前四位,但它在技术上可能非常成熟,可是缺乏较大的用户基数就意味着它们还没有经受过采纳程度测试。
虽然在本文编写的时候,它们还不适合于商业开发,但是这些工具的日后发展还是值得关注的。
通过上表的比较,还可以看出非Java平台的AOP工具没有Java平台的工具成熟,但是应当注意.NET和C++工具的用户社区正在成长。
根据表1,可以看出,从用户采用度的角度来说,AspectJ、AspectWerkz、JBossAOP和SpringAOP是领先的工具。
所有这些工具都是适合用于商业开发中的开源项目。
按字母顺序将它们排列如下,包括它们V1.0版本的发布日期:
∙AspectJ
——2001年由XeroxPARC的AOP小组发行。
目前主页在eclipse.org上,由IBM支持。
版本已经更新到1.2.1。
∙AspectWerkz
——2002年发布,由BEASystems支持。
版本更新到2.0RC2。
∙JBossAOP
——2004年作为JBoss应用程序服务器框架的扩展发布。
版本更新到1.0。
∙SpringAOP
——2004年作为Spring框架的扩展发布。
版本更新到1.1.3.
都是为了连接点
本文介绍的每个AOP工具都采用了连接点(joinpoint)模型和机制,显式地声明程序的横切结构。
虽然各个工具实现这个框架的技术非常相似,但是理解底层机制对于了解每项技术的优劣是非常重要的。
在这一节中,将回顾AOP的连接点模型以及利用连接点模型的语言模型。
支持机制
AOP工具的设计目标是把横切的问题(例如认证和事务管理)模块化。
在单独使用面向对象技术实现的的时候,处理这些问题的代码会分散在整个系统中,这种分散造成管理和发展横切结构时出现不必要的困难。
与对象提供了一种能够清楚地捕获继承结构的语言机制类似,AOP也为横切问题的良好模块化提供了同样的好处。
位于每个AOP工具核心的是连接点模型,它提供了一种机制,可以识别出在哪里发生了横切。
连接点
就是主程序和方面相遇的地方。
静态连接点允许方面定义类上的新成员。
动态连接点是方面执行与程序执行相遇的地方。
例如,普通的Java程序执行方法调用、字段设置这样的连接点。
再比如说,请考虑一下这样一个问题:
对改变
Account
状态的活动进行监视,就像在RamnivasLaddad的
AspectJinAction
一书中讨论的那样(请参阅参考资料)。
图1中的顺序图突出了在
操作上形成的一些动态连接点。
图1.突出了选中的动态连接点的UML序列图
下面的编号与图中的编号对应:
1.方法执行
连接点,与方法返回之前的生命周期对应。
2.控制流程
捕捉在控制流程序列中出现的各个连接点;
在这个例子中,在
debit()
方法调用下方的序列描述了在
调用中发生的全部连接点。
3.字段访问
连接点对应着字段的读和写;
在这个例子中,在
类上对
name
字段进行了赋值。
AspectJ和AspectWerkz项目合并
AOP技术正在迅速地向前发展,在本文的第2部分突出了领先的AOP工具的预计的发布计划。
有一个那些思想超前的读者会特别感兴趣的主题,这就是最近AspectJ与AspectWerkz项目的合并,这一合并会给AOP的发展前景带来重大的变化。
一些开发人员在这些项目上进行合作,生产AspectJ5,这是一种单一工具,融合了这里介绍的AspectJ和AspectWerkz的语法。
重要的是要注意AspectWerkz并没有正在消失。
它将成为编写AspectJ程序的另一种方法,并更名为
@AspectJ风格。
在这里可以看到,语法是AOP实现之间的主要区别因素,而核心的AOP机制通常非常相似。
AspectWerkz和AspectJ的相似性使得这两种技术可以联合。
合并可以在提供方面语法的时候提供更多的灵活性,同时保留着关键的好处(例如静态类型化和成熟的工具支持)。
有关合并的细节以及相关文档,可以从参考资料中得到。
虽然本文重点放在立刻就可以开始使用的工具上,但是这里概述的指标和优劣也适用于未来的发行版(例如AspectJ5)。
切入点、通知和类型间声明
AOP工具提供了识别连接点集合的机制,叫作切入点(pointcut)。
通知(advice)
机制指定在程序执行过程中遇到匹配的切入点时应当采取什么行动。
另外,类型间声明(inter-typedeclaration)(开放类或混合类提供了在现有类型上声明额外成员的方法。
切入点、通知和类型间声明组合在一起,使AOP语言可以清楚地表达横切问题。
方面
声明可以在标准的Java字段和方法之外包含这三类成员。
方面代表一套模块化良好的横切结构。
如下所示,不同的AOP技术实现这些方法的技术各不相同。
但是,每种技术的核心,都是连接点的访问、编辑、命名和抽象机制。
切入点可以通过显式枚举方式描述连接点集合。
应当用一个示例指定图1
所示的
的利息的三个方法调用。
虽然枚举可能很有用,但是用结构化属性的方式表示连接点通常更方便。
这类基于属性的切入点可以表示一套与“每个针对
子类型的调用”匹配的连接点,却不必强迫程序员枚举这些子类型。
这样做可以保证向系统添加由
扩展的新类时,新类会自动与切入点匹配。
切入点支持复合(composition),这就允许把简单的切入点组合成更复杂的切入点。
例如,可以把所有
调用的切入点限制在那些针对特定类或控制流程进行的调用中。
切入点的命名(naming)机制提高了可读性和复合性。
对抽象(abstraction)与具体化(concretization)的支持,可以更加容易地创建通用库,对于要应用库的特定应用程序的切入点来说,这些库可以独立定义。
最后,对切入点中公开连接点状态
的支持允许对诸如正在执行对象和方法参数之类的访问事项进行商量。
方面比较
如前所述,所有AOP工具的底层机制都是连接点和切入点、通知和类型间声明的概念。
在这些工具中,可以注意到的主要区别就是方面声明编写及应用到系统上的方式。
这些工具可用以下方法中的一种进行方面声明:
使用类似Java的代码、注释或XML。
对于某些开发人员来说,熟悉用Java语言编程方面的知识,要比熟悉语言扩展技术的优劣更重要,这些内容会在后面的小节中讨论。
对于其他人来说,了解注释和XML技术在集成上的优势,要比痛苦地把切入点当作字符串来操作更重要。
在这一节中,将使用一个常见的示例指出每个工具在方面声明技术上的差异。
请考虑图1
类的授权策略这样一个示例。
在面向对象的实现中,最常见到的,就是对认证的调用分散在
Account类的众多方法以及需要认证的其他类中。
在AOP实现中,可以明确地用一个方面捕获这个行为,而不必修改操纵帐户的代码。
不管使用什么工具声明,这个方面都需要具备以下特征:
∙一个切入点,捕捉
banking.Account
类上所有公共方法的执行。
∙一种引用正在认证的
的方式。
∙通知,在切入点指定的连接点上调用
的认证。
现在,请看这几个领先的AOP工具各自是如何处理这个方面的。
AspectJ
Aspect中的方面声明类似于Java语言中的类声明,如图2所示。
由于AspectJ是Java语言语法和语义的扩展,所以它提供了自己的一套处理方面的关键字。
除了包含字段和方法之外,AspectJ的方面声明还包含切入点和通知成员。
示例中的切入点使用了修饰符(modifier)和通配符(wildcard)模式来表达“所有公共方法”。
对帐户的访问,由
pointcut
参数提供。
通知使用这个参数,而切入点则用this(account)
把它绑定。
这样做的效果,就是捕获了正在执行的方法所隶属
对象。
否则,通知的主体与方法的主体相似。
通知可以包含认证代码,或者就像在这个示例中一样,可以调用其他方法。
图2.AspectJ的方面
构建AspectJ程序与构建Java程序类似,其中包括调用AspectJ的递增编译器,构建所有的项目源文件,包括普通的Java源文件。
运行AspectJ程序也与运行Java程序一样,请注意要把aspectjrt.jar
库添加到类路径中。
要对在系统中应用哪个方面进行配置,必须把它们加入包含列表或从中删除,包含列表会传递给编译器,可以通过IDE支持传递包含列表,如果正在Ant环境或命令行进行工作,也可以通过“.lst”包含文件传递。
注意,在第2部分中,将讨论构建AOP程序的细节以及方面设计的概念。
AspectWerkz
AspectWerkz和AspectJ之间的重要区别就是:
Authentication
现在是一个普通的Java类,而不是一个方面。
AspectWerkz、JBossAOP和SpringAOP都在没有改变Java语言语法的情况下加入了方面语义。
AspectWerkz提供了两种进行AOP声明的途径。
最常用的是注释,注释可以采用图3中的JavaV5.0风格,也可以为了与J2SEV1.4兼容采用Javadoc风格。
AspectWerkz还支持另外一种基于XML的方面声明风格。
XML风格与下面介绍的JBossAOP的风格类似,把方面声明放在单独的XML文件中。
请注意通知就是普通的方法声明。
按照约定,它被当作不同类型的方法声明,因为不应当显式地调用它,而是应该在满足特定切入点时自动运行它。
AspectWerkz的切入点声明是附加到切入点“方法”的字符串值,也可以在XML文件中独立存在。
所以,没有切入点的
import
机制,所有的类型引用必须完全规范。
对正在运行的
对象的访问技术与AspectJ相同。
请注意,规划的
@AspectJ
语法看起来与AspectWerkz注释的语法非常相似。
图3.AspectWerkz的方面
构建AspectWerkz程序会涉及一个标准的Java构建,然后会涉及到后处理。
要运行AspectWerkz程序,必须把AspectWerkz库放在类路径中。
在使用不可插入的方面的情况下,由aop.xml文件配置系统中一些方面的包含情况。
JBossAOP
JBossAOP基于XML的方面来声明风格,如图4所示。
JBoss也支持与图3所示相似的注释风格。
在XML风格中,方面、切入点和通知声明都以XML形式表示的。
通知的实现,用的是普通的Java方法,由JBossAOP框架调用。
切入点和切入点到通知的绑定都在方面中用XML注释声明。
JBoss没有显式地绑定
参数,而是提供了对当前正在执行的对象的反射访问,因此需要把类型转换到对应的类型。
注意,即将发布的JBoss会提供一些静态类型的切入点参数来解决这一问题。
图4.JBossAOP的方面
用JBoss构建方面只包括普通的Java构建。
JBossAOP的运行时截取框架(interceptionframework)负责管理切入点匹配和通知调用。
需要对启动和类路径做一些配置,但是JBossAOP的IDE插件替用户做了这些工作。
方面在jboss-aop.xml文件中配置。
SpringAOP
查看图5中的SpringAOP示例时,可以注意到其中的XML比前面介绍的技术多。
与JBossAOP类似,Spring的通知实现是带有特殊参数的Java方法,由Spring框架调用。
XML描述accountBean,Spring框架通过它访问
对象,包括通知使用的拦截器
advisor
及其匹配模式,还有应用到模式的向前(before)
通知。
图5.SpringAOP的方面
SpringAOP的技术虽然提供了更加精细的配置,但在将它用于XML时,它与JBossAOP非常类似。
构建、运行和配置SpringAOP方面的过程与JBossAOP相同,但SpringAOP依赖的是Spring框架方便的、最小化的运行时配置,所以不需要独立的启动器。
请注意,使用这个技术,只能通知从Spring框架检索出的对象。
语法差异
正如上面的图所展示的,AOP工具之间的关键差异就是处理方面声明的方式。
AspectJ是Java语言的扩展,用它可以完全在代码中对方面进行声明。
AspectWerkz和JBossAOP支持用方面元数据对Java代码进行注释,或者在独立的XML文件中对方面进行声明。
在SpringAOP中,则完全用XML对方面进行声明。
所以,在三种不同的技术中,对方面进行编程的感觉可能非常不同。
用AspectJ的代码风格,方面和切入点声明感觉起来就像Java代码。
而用JBossAOP或AspectWerkz的注释风格,感觉起来就像在现有Java元素上做的附加标签。
而用SpringAOP风格,以及AspectWerkz和JBossAOP的
XML风格
时,感觉就像使用独立的声明性XML语言。
每种技术都有它的优势,具体要由使用者决定哪个更适合需求。
所以在这一节,将简要地讨论一些能够有助于进行决策的要点。
自己的风格是什么?
不管选择哪个AOP工具,使用通知主体时只涉及到使用Java代码。
如果需要修改切入点,那么区别是非常透明的。
在使用XML风格时(就像在SpringAOP中),修改切入点包括:
从通知找到XML文件中对应的切入点声明。
从正面来说,这项技术把切入点和方面配置的工作全都局限于本地,但是如果要编辑许多通知和切入点,而且要在Java和XML之间重复地翻来覆去,那么这项工作就会变得很繁琐。
如果使用AspectWerkz或JBossAOP提供的注释风格,那么就可以把切入点的表达值从XML转移到Java成员的注释。
这样可以更容易地并发处理通知体和切入点。
如果选择了AspectJ的代码风格,那么就会发现处理切入点感觉就像处理代码,而不像是处理非结构化的字符串值。
从Java代码能得到的一切(例如“import”语句),都可以用于切入点。
对比之下,如果用AspectWerkz、JBossAOP和SpringAOP的XML和注释风格,总是需要在规范切入点中的类型引用。
简洁还是繁琐?
方面声明的风格对每个工具中使用的方面有很大的影响。
例如,支持在XML中声明方面的工具,也支持在同一XML文件中对方面应用到系统的方式进行配置。
在前面的小节中,只展示了切入点和方面声明,但是类型间声明同样受到风格选择的影响。
在AspectJ中,类型间方法声明看起来就像正常的方法声明,引用的技术也一样。
而在其他技术中,则要指定一个类,扩展额外的混合类并继承那些额外的成员,通过注释或XML添加新方法。
注意,目前AspectJ是惟一提供使用切入点的静态强制机制的工具。
表2比较了这些工具对AOP语法的关键元素的处理技术。
表2.比较领先的AOP工具中的语法
显然,从图2-5的方面声明来看,代码风格是处理AOP声明最简洁的技术。
它不需要对通知命名,也不需要显式地调用通知。
代码风格不需要显式地把通知绑定到切入点(就像XML风格那样),也不需要把通知绑定到
return
语句(这是AspectWerkz的切入点“方法”所需要的)。
对于可以在
图3
和
图4
的XML中看到的复杂设计,AspectJ对Java语言进行的语法扩展允许直接表示这些设计。
用AspectJ编写方面,感觉起来更像是编写Java代码,避免了冗余的键入,因此出错也就更少。
从不好的一面来说,Java的语法扩展代价巨大,而注释和XML风格有它们独特的优势。
最明显的就是XML风格可以控制切入点和通知的绑定。
这对于扩展和配置方面非常有益,在下面一节中将讨论这点以及不同风格带来的其他优缺点。
代码风格与注释和XML的比较
那么,应当采用代码风格,还是用注释或XML声明方面呢?
以下是基于AspectJ的Java代码的一些技术的优缺点总结:
∙简明语法充分利用对Java代码的熟悉,减少键入错误,使错误更少。
∙切入点是一级实体,因此更容易对它们进行处理。
∙对于许多开发人员,用XML进行声明性编程要比用Java语言扩展更熟悉。
∙通知到切入点的绑定不能由开发人员控制。
如果这个小结仍然无法缩小决策范围,那么不要担心。
除了用每种风格编写这些方面的感觉之外,还有更多需要考虑的东西。
当在下一节中查看语义的时候,语法决策还会出现,而且也会影响在第2部分中讨论的工具支持。
语义的相似性
虽然工具的方面声明风格之间存在主要的语法差异,但是核心的AOP语义是类似的。
每个工具都有完全相同的连接点模型的概念,都把连接点作为Java程序中的关键点,把切入点作为匹配连接点的机制,把通知作为指定连接点匹配时执行操作的机制。
表3
表4
总结了每种技术的语义。
您可以注意到,命令规范上有许多微小的差异和变化,但是各种技术最终聚合在相同的核心概念上。
这种聚合有很大的好处,因为这意味着学习曲线很容易从一项AOP技术转移到另外一项AOP技术。
剩下来要考虑的就是每种技术的差异所带来的优劣了。
回到连接点
一个AOP工具连接点模型的表达方式决定了可用的连接点粒度,以及连接点如何匹配。
每个AOP工具都提供了大量用于连接点匹配的原生切入点。
有些原生切入点只与特定类型的连接点匹配(例如,方法执行)。
其他切入点能够根据连接点的公共属性(例如,在某个控制流程中的所有连接点)匹配任何类型的连接点。
连接点的类型以及它们特定的切入点,可以分成以下几组:
∙调用(Invocation)——调用或执行方法和其他代码元素时的点。
∙初始化(Initialization)——初始化类和对象时的点。
∙访问(Access)——读写某些字段时的点。
∙异常处理(Exceptionhandling)——抛出和处理异常与错误时的点。
另外,也支持以下没有类型的切入点分类:
∙控制流程(Controlflow)——在某个流程控制流程中的连接点。
∙包含(Containment)——与包含在某个类或方法中的代码位