|
对于最新的稳定版本,请使用 Spring Framework 7.0.6! |
选择使用哪种AOP声明风格
一旦你决定使用切面是实现某个需求的最佳方法,那么如何在Spring AOP和AspectJ之间进行选择,以及在切面语言(代码)风格、@AspectJ注解风格和Spring XML风格之间进行选择呢?这些决策受到多个因素的影响,包括应用程序需求、开发工具和团队对AOP的熟悉程度。
Spring AOP 还是完整的 AspectJ?
使用最简单可行的方法。Spring AOP 比使用完整的 AspectJ 更简单,因为不需要在开发和构建过程中引入 AspectJ 编译器/织入器。如果你只需要对 Spring bean 的操作执行进行通知,那么 Spring AOP 是正确的选择。如果你需要对不由 Spring 容器管理的对象(例如,域对象)进行通知,或者你需要通知除简单方法执行之外的连接点(例如,字段获取或设置连接点等),则需要使用 AspectJ。
使用 AspectJ 时,您可以选择 AspectJ 语言语法(也称为“代码风格”)或 @AspectJ 注解风格。如果切面在您的设计中扮演重要角色,并且您可以使用 Eclipse 的 AspectJ 开发工具 (AJDT) 插件,则建议采用 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 风格时,这些信息就被封装在了一个单一模块中:即切面(aspect)。其次,XML 风格在表达能力上比 @AspectJ 风格略有限制:它仅支持“单例”(singleton)切面实例化模型,并且无法组合在 XML 中声明的命名切入点。例如,在 @AspectJ 风格中,你可以编写如下类似代码:
-
Java
-
Kotlin
@Pointcut("execution(* get*())")
public void propertyAccess() {}
@Pointcut("execution(com.xyz.Account+ *(..))")
public void operationReturningAnAccount() {}
@Pointcut("propertyAccess() && operationReturningAnAccount()")
public void accountPropertyAccess() {}
@Pointcut("execution(* get*())")
fun propertyAccess() {}
@Pointcut("execution(com.xyz.Account+ *(..))")
fun operationReturningAnAccount() {}
@Pointcut("propertyAccess() && operationReturningAnAccount()")
fun accountPropertyAccess() {}
在XML风格中,你可以声明前两个切入点:
<aop:pointcut id="propertyAccess"
expression="execution(* get*())"/>
<aop:pointcut id="operationReturningAnAccount"
expression="execution(com.xyz.Account+ *(..))"/>
XML方法的缺点是你不能通过组合这些定义来定义accountPropertyAccess切入点。
@AspectJ 风格支持额外的实例化模型和更丰富的切点组合。它具有将切面保持为模块化单元的优点。此外,@AspectJ 切面可以被 Spring AOP 和 AspectJ 共同理解(从而使用)。因此,如果你之后决定需要 AspectJ 的功能来实现额外的需求,你可以轻松迁移到经典的 AspectJ 配置。通常情况下,Spring 团队建议在实现超出简单的企业服务配置之外的自定义切面时,优先选择 @AspectJ 风格。