5.6选择要使用的AOP声明样式

一旦确定某个方面是实现给定需求的最佳方法,那么如何决定使用SpringAOP或AspectJ,以及Aspect语言(代码)样式、@AspectJ注解样式或SpringXML样式之间的关系呢?这些决策受许多因素的影响,包括应用程序需求、开发工具和团队对AOP的熟悉程度。

5.6.1 Spring AOP 还是全部使用 AspectJ?

用最简单的方法。SpringAOP比使用完整的AspectJ简单,因为不需要在开发和构建过程中引入AspectJ编译器/weaver。如果你只需要advise Spring Beans的执行操作,那么SpringAOP是正确的选择。如果需要advise不由Spring容器管理的对象(通常是域对象),则需要使用AspectJ。如果希望advise连接点而不是简单的方法执行(例如,field get或 set join points等),还需要使用aspectj。

使用aspectj时,可以选择aspectj语言语法(也称为“代码样式”)或@Aspectj注解样式。显然,如果你不使用Java 5 +,那么你就已经选择了:使用代码风格。如果aspects在你的设计中起着很大的作用,并且你能够为Eclipse使用AspectJ开发工具(AJDT)插件,那么AspectJ语言语法是首选选项。它更干净、更简单,因为语言是专门为编写方面而设计的。如果你不使用Eclipse或仅在你的应用程序中不起主要作用的几个方面,你可能需要考虑使用@AspectJ样式,在IDE中坚持常规Java编译,并将一个方面编织阶段添加到生成脚本中。

5.6.2 @AspectJ 或者 Spring AOP XML?

如果你选择使用SpringAOP,那么你可以选择@Aspectj或XML样式。有各种各样的权衡需要考虑。

XML样式可能对现有的Spring用户最熟悉,并且由真正的Pojos支持。当使用AOP作为配置企业服务的工具时,XML是一个不错的选择(一个好的测试是你是否将切入点表达式视为你可能希望独立更改的配置的一部分)。使用XML样式,可以从配置中更清楚地看到系统中存在哪些方面。

XML样式有两个缺点。首先,它并没有将它所处理的需求的实现完全封装在一个地方。DRY原则认为系统中任何知识都应该有一个单一的、明确的、权威的表示。当使用XML样式时,如何实现需求的知识将在支持bean类的声明和配置文件中的XML中分割开来。当你使用@Aspectj样式时,这个信息被封装在一个aspect模块中。其次,XML样式在它可以表示的内容上比@Aspectj样式稍有限制:只支持“singleton”方面实例化模型,并且不可能将XML中声明的命名切入点组合在一起。例如,在@Aspectj样式中,可以编写如下内容:

@Pointcut("execution(* get*())")
public void propertyAccess() {}
@Pointcut("execution(org.xyz.Account+ *(..))")
public void operationReturningAnAccount() {}
@Pointcut("propertyAccess() && operationReturningAnAccount()")
public void accountPropertyAccess() {}

在XML样式中,可以声明前两个切入点:

<aop:pointcut id="propertyAccess"
expression="execution(* get*())"/>
<aop:pointcut id="operationReturningAnAccount"
expression="execution(org.xyz.Account+ *(..))"/>

XML方法的缺点是不能通过组合这些定义来定义accountPropertyAccess切入点。

@Aspectj样式支持附加的实例化模型和更丰富的切入点组合。它具有将方面作为模块化单元保留的优点。它还具有这样的优势,@Aspectj方面可以被SpringAOP和aspectj理解(从而被消费)。因此,如果你稍后决定需要AspectJ的功能来实现额外的需求,你可以轻松地迁移到经典的AspectJ设置。总的来说,Spring团队除了简单的企业服务配置外,更喜欢@Aspectj风格的定制方面。