跳到主要内容

选择使用哪种 AOP 声明风格

ChatGPT-4o-mini 中英对照 Choosing which AOP Declaration Style to Use

一旦您决定某个方面是实现特定需求的最佳方法,您如何在使用 Spring AOP 或 AspectJ 之间进行选择,以及在 Aspect 语言(代码)风格、@AspectJ 注解风格或 Spring XML 风格之间进行选择?这些决策受到多个因素的影响,包括应用程序需求、开发工具以及团队对 AOP 的熟悉程度。

Spring AOP 还是 Full AspectJ?

使用能够工作的最简单的东西。Spring AOP 比使用完整的 AspectJ 更简单,因为不需要在开发和构建过程中引入 AspectJ 编译器/织入器。如果您只需要对 Spring bean 上的操作执行进行建议,Spring AOP 是正确的选择。如果您需要对不受 Spring 容器管理的对象(例如,通常的领域对象)进行建议,则需要使用 AspectJ。如果您希望对简单方法执行以外的连接点进行建议(例如,字段获取或设置连接点等),您也需要使用 AspectJ。

当你使用 AspectJ 时,你可以选择 AspectJ 语言语法(也称为“代码风格”)或 @AspectJ 注解风格。如果切面在你的设计中扮演重要角色,并且你能够使用 AspectJ Development Tools (AJDT) 插件来进行 Eclipse 开发,那么 AspectJ 语言语法是首选选项。它更清晰、更简单,因为该语言是专门设计用于编写切面的。如果你不使用 Eclipse 或者只有少量切面在你的应用程序中并不占主要地位,你可能想考虑使用 @AspectJ 风格,继续在你的 IDE 中使用常规 Java 编译,并在你的构建脚本中添加切面织入阶段。

@AspectJ 还是 XML 用于 Spring AOP?

如果您选择使用 Spring AOP,您可以选择 @AspectJ 或 XML 风格。需要考虑各种权衡。

XML 风格可能对现有的 Spring 用户最为熟悉,并且它是基于真正的 POJO。当使用 AOP 作为配置企业服务的工具时,XML 可以是一个不错的选择(一个好的测试是你是否认为切点表达式是你可能想要独立更改的配置的一部分)。使用 XML 风格时,从你的配置中可以说更清楚地看出系统中存在哪些方面。

XML 风格有两个缺点。首先,它没有在一个地方完全封装所处理需求的实现。DRY 原则指出,系统内的任何知识片段都应该有一个单一、明确、权威的表示。当使用 XML 风格时,关于需求如何实现的知识分散在后台 bean 类的声明和配置文件中的 XML 之间。当你使用 @AspectJ 风格时,这些信息被封装在一个单一的模块中:切面。其次,XML 风格在表达能力上略微有限于 @AspectJ 风格:仅支持 "singleton" 切面实例化模型,并且无法组合在 XML 中声明的命名切入点。例如,在 @AspectJ 风格中,你可以写如下内容:

@Pointcut("execution(* get*())")
public void propertyAccess() {}

@Pointcut("execution(com.xyz.Account+ *(..))")
public void operationReturningAnAccount() {}

@Pointcut("propertyAccess() && operationReturningAnAccount()")
public void accountPropertyAccess() {}
java

在 XML 风格中,您可以声明前两个切入点:

<aop:pointcut id="propertyAccess"
expression="execution(* get*())"/>

<aop:pointcut id="operationReturningAnAccount"
expression="execution(com.xyz.Account+ *(..))"/>
xml

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

@AspectJ 风格支持额外的实例化模型和更丰富的切点组合。它的优势在于将切面保持为一个模块化单元。它还有一个优点,即 @AspectJ 切面可以被 Spring AOP 和 AspectJ 理解(因此也可以被使用)。因此,如果您后来决定需要 AspectJ 的功能来实现额外的需求,您可以轻松迁移到经典的 AspectJ 设置。一般来说,Spring 团队更倾向于使用 @AspectJ 风格来处理简单的企业服务配置之外的自定义切面。