AOP@Work:AOP工具比较,第1部分-语言机制

简介:AOP 技术的时代已经来临,但是怎样才能为项目选择正确的工具呢?在 新推出的 AOP@Work 系列的第一篇文章中,面向方面(aspect-oriented)的编程 专家 Mik Kersten 将比较 4 个领先的 AOP 工具(AspectJ、AspectWerkz、 JBoss AOP 和 Spring AOP),帮助大家判断应该选择哪一个工具。本文由两个部 分组成,在文中,作者将重点介绍这些工具的语言机制和不同技术的优劣。他分 别用 4 种工具编写同一个示例,让读者感觉到它们之间的高级区别。他还将讨论 每种工具的语法技术对 AOP 语义产生的效果。在文章结束时,作者将对工具的核 心语言机制(例如切入点匹配和组合、通知的格式、连接点上下文)进行深入比 较。注意,本文将解释最近宣布的 AspectJ 和 AspectWerkz 项目合并的意义。

面向方面编程(AOP)在 Java™ 平台上变得日益流行。随着 AOP 出版物和会议的增加,这项技术的工具与实现越来越多。虽然人们很清楚 AOP 是 面向对象技术的补充,但是 Java 开发人员该如何评估当前的 AOP 工具,特别是 每项新技术实现的优劣,这方面则相对不那么清楚。

本文有两部分,而且 本文还是 developerWorks 上一个新的 AOP 系列的第一篇文章。在本文中,将概 述 AOP 工具当前的技术状况,比较对于该技术而言最成熟的一些方法:AspectJ 、AspectWerkz、JBoss AOP、和 Spring AOP,并对比与每种方法的采用有关的问 题。文中还会解释最近宣布的 AspectJ 和 AspectWerkz 项目合并的意义(请参 阅参考资料)。

本文无意作为 AOP 的介绍或某个特定 AOP 实现的入门读 物。而是将对目前使用最普遍的 AOP 技术进行概述。对每个工具的语言机制和工 具支持的内在优劣进行探讨,将有助于为项目选择最合适的技术。这里定义的指 标还会让读者更加容易地评估即将推出的 AOP 工具和特性。关于 developerWorks 上介绍 AOP 的最新文章列表,请参阅参考资料。

请注意 本文有两个部分,为了方便读者,两部分同时发布。第 1 部分侧重于这 4 个领 先工具各自的 AOP 语言机制处理技术,其中包括工具的方面语法(aspect syntax)和切入点的表示、用来声明方面的机制范围等主题。第 2 部分继续深入 介绍领先的 AOP 实现如何与现有的开发环境、工具和库进行集成。这一部分包括 以下主题:方面设计器、IDE 插件、可伸缩性和 AOP 工具将来的发展方向,还包 括对最近 AspectJ 和 AspectWerkz 项目合并的关注。

选择成熟的工具

AOP 是一项新技术,所以,并不是现有的所有工具都已经成熟到适用于商 业开发。判断成熟度的一个主要因素是用户的采用程度。在考虑把一项新编程技 术应用到商用之前,这项技术必须从活跃的用户社区的反馈中得到强化。表 1 显 示了 aosd.net 上列出的目前可以使用的 AOP 工具(请参阅参考资料)。每个工 具的用户列表贴子数量可以表明它的用户基数(省略了贴子的实际数量,因为单 独一个月的统计可能给读者造成误解)。

表 1. 在 2004 年 11 月 AOP 工具用户列表中的贴子数量

请注意 Spring 的 AOP 部分没有形成一个独立的下载或用户社团,所 以用户基数相当比例的用户可能没有给 Spring AOP 发贴,而是投在别的主题上 了。在 aosd.net 上还列出了 4 个额外的工具,但是它们要么缺乏用户讨论论坛 ,要么在 11 月没有贴子。

AOP 工具虽然没有列在表中前四位,但它在技 术上可能非常成熟,可是缺乏较大的用户基数就意味着它们还没有经受过采纳程 度测试。虽然在本文编写的时候,它们还不适合于商业开发,但是这些工具的日 后发展还是值得关注的。通过上表的比较,还可以看出非 Java 平台的 AOP 工具 没有 Java 平台的工具成熟,但是应当注意 .NET 和 C++ 工具的用户社区正在成 长。

根据表 1,可以看出,从用户采用度的角度来说,AspectJ、 AspectWerkz、JBoss AOP 和 Spring AOP 是领先的工具。所有这些工具都是适合 用于商业开发中的开源项目。按字母顺序将它们排列如下,包括它们 V1.0 版本 的发布日期:

AspectJ —— 2001 年由 Xerox PARC 的 AOP 小组发行。目前主页在 eclipse.org 上,由 IBM 支持。版本已经更新到 1.2.1 。

AspectWerkz —— 2002 年发布,由 BEA Systems 支持。 版本更新到 2.0RC2。

JBoss AOP —— 2004 年作为 JBoss 应用程序服务器框架的扩展发布。版本 更新到 1.0。

Spring AOP —— 2004 年作为 Spring 框架的扩展发布。版本更新到 1.1.3.

都是为了连接点

本文介绍的每个 AOP 工具都采用了连接点(join point)模型和机制,显式 地声明程序的横切结构。虽然各个工具实现这个框架的技术非常相似,但是理解 底层机制对于了解每项技术的优劣是非常重要的。在这一节中,将回顾 AOP 的连 接点模型以及利用连接点模型的语言模型。

支持机制

AOP 工具的设计目标是把横切的问题(例如认证和事务管理)模块化。在单独 使用面向对象技术实现的的时候,处理这些问题的代码会分散在整个系统中,这 种分散造成管理和发展横切结构时出现不必要的困难。与对象提供了一种能够清 楚地捕获继承结构的语言机制类似,AOP 也为横切问题的良好模块化提供了同样 的好处。位于每个 AOP 工具核心的是连接点模型,它提供了一种机制,可以识别 出在哪里发生了横切。

连接点 就是主程序和方面相遇的地方。静态连接点允许方面定义类上的新成 员。动态连接点是方面执行与程序执行相遇的地方。例如,普通的 Java 程序执 行方法调用、字段设置这样的连接点。再比如说,请考虑一下这样一个问题:对 改变 Account 状态的活动进行监视,就像在 Ramnivas Laddad 的 AspectJ in Action 一书中讨论的那样(请参阅参考资料)。 图 1 中的顺序图突出了在 Account 操作上形成的一些动态连接点。

图 1. 突出了选中的动态连接点的 UML 序列图

下面的编号与图中的编号对应:

方法执行 连接点,与方法返回之前的生命周期对应。

控制流程 捕捉在控制流程序列中出现的各个连接点;在这个例子中,在 debit() 方法调用下方的序列描述了在 debit() 调用中发生的全部连接点。

字段访问 连接点对应着字段的读和写;在这个例子中,在 Account 类上对 name 字段进行了赋值。

切入点、通知和类型间声明

AOP 工具提供了识别连接点集合的机制,叫作切入点(pointcut)。通知 (advice) 机制指定在程序执行过程中遇到匹配的切入点时应当采取什么行动。 另外,类型间声明(inter-type declaration)(开放类或混合类提供了在现有 类型上声明额外成员的方法。切入点、通知和类型间声明组合在一起,使 AOP 语 言可以清楚地表达横切问题。方面 声明可以在标准的 Java 字段和方法之外包含 这三类成员。方面代表一套模块化良好的横切结构。如下所示,不同的 AOP 技术 实现这些方法的技术各不相同。但是,每种技术的核心,都是连接点的访问、编 辑、命名和抽象机制。

切入点可以通过显式枚举方式描述连接点集合。应当用一个示例指定图 1 所 示的 Account 的利息的三个方法调用。虽然枚举可能很有用,但是用结构化属性 的方式表示连接点通常更方便。这类基于属性的切入点可以表示一套与“每个针 对 Account 子类型的调用”匹配的连接点,却不必强迫程序员枚举这些子类型。 这样做可以保证向系统添加由 Account 扩展的新类时,新类会自动与切入点匹配 。

切入点支持复合(composition),这就允许把简单的切入点组合成更复杂的 切入点。例如,可以把所有 Account 调用的切入点限制在那些针对特定类或控制 流程进行的调用中。切入点的命名(naming)机制提高了可读性和复合性。对抽 象(abstraction)与具体化(concretization)的支持,可以更加容易地创建通 用库,对于要应用库的特定应用程序的切入点来说,这些库可以独立定义。最后 ,对切入点中公开连接点状态 的支持允许对诸如正在执行对象和方法参数之类的 访问事项进行商量。

方面比较

如前所述,所有 AOP 工具的底层机制都是连接点和切入点、通知和类型间声 明的概念。在这些工具中,可以注意到的主要区别就是方面声明编写及应用到系 统上的方式。这些工具可用以下方法中的一种进行方面声明:使用类似 Java 的 代码、注释或 XML。对于某些开发人员来说,熟悉用 Java 语言编程方面的知识 ,要比熟悉语言扩展技术的优劣更重要,这些内容会在后面的小节中讨论。对于 其他人来说,了解注释和 XML 技术在集成上的优势,要比痛苦地把切入点当作字 符串来操作更重要。

在这一节中,将使用一个常见的示例指出每个工具在方面声明技术上的差异。 请考虑图 1 所示的 Account 类的授权策略这样一个示例。在面向对象的实现中 ,最常见到的,就是对认证的调用分散在 Account 类的众多方法以及需要认证的 其他类中。在 AOP 实现中,可以明确地用一个方面捕获这个行为,而不必修改操 纵帐户的代码。不管使用什么工具声明,这个方面都需要具备以下特征:

一个切入点,捕捉 banking.Account 类上所有公共方法的执行。

一种引用正在认证的 Account 的方式。

通知,在切入点指定的连接点上调用 Account 的认证。

现在,请看这几个领先的 AOP 工具各自是如何处理这个方面的。

AspectJ

Aspect 中的方面声明类似于 Java 语言中的类声明,如图 2 所示。由于 AspectJ 是 Java 语言语法和语义的扩展,所以它提供了自己的一套处理方面的 关键字。除了包含字段和方法之外,AspectJ 的方面声明还包含切入点和通知成 员。示例中的切入点使用了修饰符(modifier)和通配符(wildcard)模式来表 达“所有公共方法”。对帐户的访问,由 pointcut 参数提供。通知使用这个参 数,而切入点则用 this(account) 把它绑定。这样做的效果,就是捕获了正在执 行的方法所隶属 Account 对象。否则,通知的主体与方法的主体相似。通知可以 包含认证代码,或者就像在这个示例中一样,可以调用其他方法。

图 2. AspectJ 的方面

构建 AspectJ 程序与构建 Java 程序类似,其中包括调用 AspectJ 的递增编 译器,构建所有的项目源文件,包括普通的 Java 源文件。运行 AspectJ 程序也 与运行 Java 程序一样,请注意要把 aspectjrt.jar 库添加到类路径中。要对在 系统中应用哪个方面进行配置,必须把它们加入包含列表或从中删除,包含列表 会传递给编译器,可以通过 IDE 支持传递包含列表,如果正在 Ant 环境或命令 行进行工作,也可以通过“.lst” 包含文件传递。注意,在第 2 部分中,将讨 论构建 AOP 程序的细节以及方面设计的概念。

AspectWerkz

AspectWerkz 和 AspectJ 之间的重要区别就是: Authentication 现在是一 个普通的 Java 类,而不是一个方面。AspectWerkz、JBoss AOP 和 Spring AOP 都在没有改变 Java 语言语法的情况下加入了方面语义。AspectWerkz 提供了两 种进行 AOP 声明的途径。最常用的是注释,注释可以采用图 3 中的 Java V5.0 风格,也可以为了与 J2SE V1.4 兼容采用 Javadoc 风格。AspectWerkz 还支持 另外一种基于 XML 的方面声明风格。XML 风格与下面介绍的 JBoss AOP 的风格 类似,把方面声明放在单独的 XML 文件中。

请注意通知就是普通的方法声明。按照约定,它被当作不同类型的方法声明, 因为不应当显式地调用它,而是应该在满足特定切入点时自动运行它。 AspectWerkz 的切入点声明是附加到切入点“方法”的字符串值,也可以在 XML 文件中独立存在。所以,没有切入点的 import 机制,所有的类型引用必须完全 规范。对正在运行的 Account 对象的访问技术与 AspectJ 相同。请注意,规划 的 @AspectJ 语法看起来与 AspectWerkz 注释的语法非常相似。

图 3. AspectWerkz 的方面

构建 AspectWerkz 程序会涉及一个标准的 Java 构建,然后会涉及到后处理 。要运行 AspectWerkz 程序,必须把 AspectWerkz 库放在类路径中。在使用不 可插入的方面的情况下,由 aop.xml 文件配置系统中一些方面的包含情况。

JBoss AOP

JBoss AOP 基于 XML 的方面来声明风格,如图 4 所示。JBoss 也支持与图 3 所示相似的注释风格。在 XML 风格中,方面、切入点和通知声明都以 XML 形式 表示的。通知的实现,用的是普通的 Java 方法,由 JBoss AOP 框架调用。切入 点和切入点到通知的绑定都在方面中用 XML 注释声明。JBoss 没有显式地绑定 Account 参数,而是提供了对当前正在执行的对象的反射访问,因此需要把类型 转换到对应的类型。注意,即将发布的 JBoss 会提供一些静态类型的切入点参数 来解决这一问题。

图 4. JBoss AOP 的方面

用 JBoss 构建方面只包括普通的 Java 构建。JBoss AOP 的运行时截取框架 (interception framework)负责管理切入点匹配和通知调用。需要对启动和类 路径做一些配置,但是 JBoss AOP 的 IDE 插件替用户做了这些工作。方面在 JBoss-aop.xml 文件中配置。

Spring AOP

查看图 5 中的 Spring AOP 示例时,可以注意到其中的 XML 比前面介绍的技 术多。与 JBoss AOP 类似,Spring 的通知实现是带有特殊参数的 Java 方法, 由 Spring 框架调用。XML 描述 accountBean,Spring 框架通过它访问 Account 对象,包括通知使用的拦截器 advisor 及其匹配模式,还有应用到模 式的向前(before) 通知。

图 5. Spring AOP 的方面

Spring AOP 的技术虽然提供了更加精细的配置,但在将它用于 XML 时,它与 JBoss AOP 非常类似。构建、运行和配置 Spring AOP 方面的过程与 JBoss AOP 相同,但 Spring AOP 依赖的是 Spring 框架方便的、最小化的运行时配置,所 以不需要独立的启动器。请注意,使用这个技术,只能通知从 Spring 框架检索 出的对象。

语法差异

正如上面的图所展示的,AOP 工具之间的关键差异就是处理方面声明的方式。 AspectJ 是 Java 语言的扩展,用它可以完全在代码中对方面进行声明。 AspectWerkz 和 JBoss AOP 支持用方面元数据对 Java 代码进行注释,或者在独 立的 XML 文件中对方面进行声明。在 Spring AOP 中,则完全用 XML 对方面进 行声明。所以,在三种不同的技术中,对方面进行编程的感觉可能非常不同。用 AspectJ 的代码风格,方面和切入点声明感觉起来就像 Java 代码。而 用 JBoss AOP 或 AspectWerkz 的注释风格,感觉起来就像在现有 Java 元素上做的附加标签。而用 Spring AOP 风格,以及 AspectWerkz 和 JBoss AOP 的 XML 风格 时,感觉就像使用独立的声明性 XML 语言。

每种技术都有它的优势,具体要由使用者决定哪个更适合需求。所以在这一节 ,将简要地讨论一些能够有助于进行决策的要点。

自己的风格是什么?

不管选择哪个 AOP 工具,使用通知主体时只涉及到使用 Java 代码。如果需 要修改切入点,那么区别是非常透明的。在使用 XML 风格时(就像在 Spring AOP 中),修改切入点包括:从通知找到 XML 文件中对应的切入点声明。从正面 来说,这项技术把切入点和方面配置的工作全都局限于本地,但是如果要编辑许 多通知和切入点,而且要在 Java 和 XML 之间重复地翻来覆去,那么这项工作就 会变得很繁琐。

如果使用 AspectWerkz 或 JBoss AOP 提供的注释风格,那么就可以把切入点 的表达值从 XML 转移到 Java 成员的注释。这样可以更容易地并发处理通知体和 切入点。如果选择了 AspectJ 的代码风格,那么就会发现处理切入点感觉就像处 理代码,而不像是处理非结构化的字符串值。从 Java 代码能得到的一切(例如 “import”语句),都可以用于切入点。对比之下,如果用 AspectWerkz、JBoss AOP 和 Spring AOP 的 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)—— 读写某些字段时的点。

异常处理(Exception handling)—— 抛出和处理异常与错误时的点。

另外,也支持以下没有类型的切入点分类:

控制流程(Control flow)—— 在某个流程控制流程中的连接点。

包含(Containment)—— 与包含在某个类或方法中的代码位置对应的连接点 。

条件(Conditional)—— 特定预测为真的连接点。

如表 3 所示,每个工具实现连接点模型的方式,以及它们用来匹配连接点的 原生切入点,都略有差异。注意,在某些情况下(在括号中表示),连接点不用 切入点标识。

表 3. 连接点和用来匹配连接点的原生切入点

要富于表现力还是要简单?

在这里主要的优劣在于富于表现力和简单性的比较。更加完整和精细的切入点 集合允许通过方面访问程序执行中更多有趣的点。例如,与持久性有关的方面可 能需要访问对象的初始化连接点。但是这类完整性也会带来额外的复杂性和更陡 峭的学习曲线。许多 Java 程序员并不区分调用和执行,而且没有几个人需要理 解初始化的微妙之处。而且许多常用的方面被当作是辅助性的,所以是否有表现 力与应用程序的功能并没有紧密耦合。在常用的辅助性方面,例如监视和日志, 通常只利用了粗粒度的切入点(例如方法执行)。从反面来看,更广泛的切入点 集合确实具备量入为出的属性,因为切入点可以边用边学。如果不想用切入点制 作程序,那么会造成面向对象代码的强制重构,例如:以 init() 方法的形式公开类的初始化。

AspectJ 和 AspectWerkz 的连接点模型差不多完全融合,而且已经成为最近 的合并的关键促进者之一。JBoss AOP 模型几乎同样有表现力,只是为了简单性 而遗漏了一些不太常用的连接点。一个明显的差异是:在 JBoss Aop 中,不能把 控制流程表示成“在这个切入点的执行之下的所有连接点”。相反,程序员需要 手动列出调用堆栈中的每个调用。

Spring AOP 采用了不同的技术,目的是限制它的连接点模型的表现力。这使 它特别容易采用,而且对于一些粗粒度的横切很有用。即将发行的版本将与 AspectJ 集成,提供与精细横切机制的互操作性。

连接点模型的表现力与简单性的比较

一些项目可以从更有表现力的连接点模型(例如 AspectWerkz、AspectJ 和 JBoss AOP 提供的)获益,所以最好还是采用 Spring AOP 粗粒度的方便性?以 下是更有表现力的模型固有优缺点的一个总结,多考虑一下这些方面会对您有所 帮助:

了解更多知识 。

对于粗粒度的横切和辅助性方面,只需要很少的切入点。

没有精细的切入点,许多方面就不能表达。

使用新切入点的学习曲线是随用随学。

语言机制

我将用每种技术语言机制的详细对比结束 AOP 工具比较的第一部分的讨论。 表 4 是 4 个工具的 AOP 语言的概括。下面讨论了最明显的区别。

表 4. 领先的 AOP 工具的语义概括

切入点匹配和复合:AspectJ、AspectWerkz 和 JBoss AOP 提供了类似的类型 模式支持。它们三个都允许签名方面的匹配,对于 Java 5 应用程序来说,这些 匹配包括注释和泛型。AspectJ 和 AspectWerkz 提供了一种简洁的引用多个类型 的技术(例如 Account+ 表示帐户的所有子类型)。所有的工具都支持通配符匹 配。Spring AOP 还提供了对正则表达式的支持。虽然这看起来可能是一个强大的 优势,但还是要指出其他技术已经选择了放弃正则表达式,好让切入点读起来不 是太难,同时不会存在潜在的损害。切入点复合操作符基本上都是相同的。 Spring AOP 不提供“非”操作,这个操作通常与没有在 Spring AOP 连接点模型 的容器(containment)连接点结合使用。

通知形式:AspectJ 支持比其他技术更多的通知形式,而 JBoss AOP 只支持 一种通知形式。每种通知形式都可以表达成 around 通知,所以 JBoss 的技术是 无限的,而且它确实提供了额外的简单性。不好的一面是它损失了简洁性,这一 点可以从需要进行额外的调用才能继续执行原来的方法调用(如 图 4 所示)看 得出来,而如果用 before 进行通知,这一点就是不必要的。还请注意,强迫通 知去遵守普通的 Java 规则(就像注释和 XML 风格做的那样),在一些情况下容 易出问题,因为这些规则是为方法设计的。AspectJ 拥有把被通知方法的异常“ 软化”的能力,这很有用,但是不符合方法异常检测的标准语义。

连接点上下文:在 AspectJ 和 AspectWerkz 中,通过指定和绑定切入点参数 访问动态连接点的状态,类似于在 Java 语言中声明方法参数的技术(请参阅图 2 和 图 3)。这为连接点上下文提供了静态类型化的好处。JBoss AOP 和 Spring AOP 反射性地访问连接点的状态,这消除了在切入点表达式中参数绑定的 复杂性,代价是参数静态类型化。Java 程序员习惯了方法参数静态类型化带来的 好处,同时还可以从切入点参数的静态类型化得到同样的好处。所以,在 JBoss AOP 最近的发行版本中,有提供静态类型化的“args” 的计划。

实例化:在所有的工具中,方面的实例化是由 per 子句控制的。正如所料, Spring AOP 的实例化模型更简单。对于额外的实例化机制的支持,则意味着可以 把方面编写成只能应用于特定的动态上下文环境中,不用编写代码保存这个上下 文并测试其他方面是否该应用这个方面。主要的区别因素是 AspectJ 支持在每个 控制流程进行方面初始化,AspectWerkz 支持每个线程的初始化,而 JBoss 则支 持每个连接点的初始化。哪种最有用则取决于具体的需求。

扩展性:方面的扩展性支持库方面的部署,这样可以在日后为特定程序而将这 些库方面具体化。例如,一个方面库可以提供应用程序监视需要的全部逻辑和基 础设施。但是,要采用某个特定项目的库,那么库使用的切入点必须扩展成应用 程序特定的连接点。AspectJ 用抽象方面支持扩展性,抽象方面包含抽象的切入 点和具体的通知。扩展抽象方面的子方面必须具体化切入点。AspectWerkz 和 JBoss AOP 使用了完全不同的技术,没有使用抽象切入点机制。扩展是通过生成 方面的子类、并在 XML 中或通过注释定义新的通知绑定而实现的。切入点到通知 的显式绑定为 AspectWerkz 和 JBoss AOP 提供了显著优势,从而可以很容易地 把方面扩展到新系统,无需要生成子类。方面库的使用数据正在日益增多,这些 将决定与其他技术使用的 Java 风格的继承和切入点绑定相比,AspectJ 特殊的 AOP 继承形式是更好还是更差。

每项技术在处理 AOP 的语言机制时,都提供了自己独特的优缺点。用一个简 单的列表来总结这些优缺点是不可能的,因为对于不同的项目,每项技术的好处 是各不相同的。但是,以上信息为选择工具或者遇到关键问题时寻找替代品提供 了指南。

结束语

为项目选择一个 AOP 工具所面临的难题在于比较每种工具的优劣,同时不要 让自己迷失其中。AOP工具比较的第一部分强调了 4 种领先的 AOP 技术的核心机 制,并对比了它们的相似与不同之处。

如果本文是在十年之前报道一项新的模块化技术,那么我们可能就此打住,开 始用自己选择的风格来编写方面 —— 可能是在命令行用 Emacs 或其他文本编辑 器构建。但是今天,如果没有深入研究一项新技术如何与现有的开发环境和其他 工具集成,人们是不会轻易地考虑采用它的。

所以,本文的第二部分把重点放在集成因素对 AOP工具选择的影响。在其他因 素之中,将讨论每个工具如何处理方面的编译与设计,以及如何依据 IDE 集成与 工具支持将它们都组合在一起。我还会比较这些工具的基本特性,看看它们背后 到底是什么,包括进一步探讨 AspectJ 与 AspectWerkz 项目合并之后我们可以 期盼从中得到什么。

而开始追寻他内心世界的真正财富

AOP@Work:AOP工具比较,第1部分-语言机制

相关文章:

你感兴趣的文章:

标签云: