Choosing which AOP Declaration Style to Use
应用程序要求:AspectJ 适用于通知 Spring 外部对象和更高级别的连接点。
开发工具:AspectJ 语言语法更简洁,需要 AspectJ 开发工具支持。
团队 AOP 经验:Spring XML 样式可能更熟悉,但 @AspectJ 样式提供更好的封装和灵活性。
最终,@AspectJ 样式通常是首选,因为它提供了模块化、更好的切点组合和与 AspectJ 的兼容性。
一旦你决定针对给定的需求实现一个切面是最佳方法,你如何在 Spring AOP 与 AspectJ 之间做出决定,以及在 Aspect 语言(代码)样式、@AspectJ 注解样式或 Spring XML 样式之间做出决定?这些决定会受到多种因素的影响,包括应用程序要求、开发工具以及团队对 AOP 的熟悉程度。
Once you have decided that an aspect is the best approach for implementing a given requirement, how do you decide between using Spring AOP or AspectJ and between the Aspect language (code) style, the @AspectJ annotation style, or the Spring XML style? These decisions are influenced by a number of factors including application requirements, development tools, and team familiarity with AOP.
Spring AOP or Full AspectJ?
使用最简单、可行的选择。Spring AOP 比使用完整的 AspectJ 更简单,因为无需将 AspectJ 编译器/织入引入你的开发和构建过程中。如果你只需要通知在 Spring Bean 上执行操作,Spring AOP 是正确的选择。如果你需要通知 Spring 容器未管理的对象(比如典型的域对象),你需要使用 AspectJ。如果你希望通知简单的执行方法以外的连接点(例如字段 get 或 set 连接点等等),也需要使用 AspectJ。
Use the simplest thing that can work. Spring AOP is simpler than using full AspectJ, as there is no requirement to introduce the AspectJ compiler / weaver into your development and build processes. If you only need to advise the execution of operations on Spring beans, Spring AOP is the right choice. If you need to advise objects not managed by the Spring container (such as domain objects, typically), you need to use AspectJ. You also need to use AspectJ if you wish to advise join points other than simple method executions (for example, field get or set join points and so on).
当你使用 AspectJ 时,你可以选择 AspectJ 语言语法(也称为“代码样式”)或 @AspectJ 注解样式。如果切面在你的设计中扮演着更重要的角色,并且你可以对 Eclipse 使用 AspectJ 开发工具 (AJDT) 插件,则 AspectJ 语言语法是首选。它更简洁、简单,因为该语言有目的地设计用于编写切面。如果你不使用 Eclipse 或只有几个在应用程序中不起主要作用的切面,你可以考虑使用 @AspectJ 样式,坚持在你的 IDE 中进行常规 Java 编译,并向你的构建脚本添加一个切面织入阶段。
When you use AspectJ, you have the choice of the AspectJ language syntax (also known as the "code style") or the @AspectJ annotation style. If aspects play a large role in your design, and you are able to use the AspectJ Development Tools (AJDT) plugin for Eclipse, the AspectJ language syntax is the preferred option. It is cleaner and simpler because the language was purposefully designed for writing aspects. If you do not use Eclipse or have only a few aspects that do not play a major role in your application, you may want to consider using the @AspectJ style, sticking with regular Java compilation in your IDE, and adding an aspect weaving phase to your build script.
@AspectJ or XML for Spring AOP?
如果你选择使用 Spring AOP,则可以使用 @AspectJ 或 XML 样式。需要考虑各种取舍。
If you have chosen to use Spring AOP, you have a choice of @AspectJ or XML style. There are various tradeoffs to consider.
对于现有的 Spring 用户来说,XML 样式可能最熟悉,并且它由真正的 POJO 支持。当使用 AOP 作为配置企业服务的工具时,XML 可能是不错的选择(一个很好的测试是考虑你的切点表达式是否是你可能需要独立更改的配置的一部分)。通过 XML 样式,从配置中可以更清楚地看出系统中存在哪些切面。
The XML style may be most familiar to existing Spring users, and it is backed by genuine POJOs. When using AOP as a tool to configure enterprise services, XML can be a good choice (a good test is whether you consider the pointcut expression to be a part of your configuration that you might want to change independently). With the XML style, it is arguably clearer from your configuration which aspects are present in the system.
XML 样式有两个缺点。首先,它没有将对需求的实现 完全封装在同一地点。DRY 原则表明,系统内的任何知识片段应该有单独、明确、权威的表示形式。使用 XML 样式时,有关如何实现需求的知识分布在后端 bean 类的声明和配置文件中的 XML 中。使用 @AspectJ 样式时,此信息封装在一个模块中:方面。其次,XML 样式在表达功能上略受限制,因为它仅支持“单例”方面实例化模型,并且无法结合在 XML 中声明的命名切入点。例如,在 @AspectJ 样式中,您可以编写类似以下内容:
The XML style has two disadvantages. First, it does not fully encapsulate the implementation of the requirement it addresses in a single place. The DRY principle says that there should be a single, unambiguous, authoritative representation of any piece of knowledge within a system. When using the XML style, the knowledge of how a requirement is implemented is split across the declaration of the backing bean class and the XML in the configuration file. When you use the @AspectJ style, this information is encapsulated in a single module: the aspect. Secondly, the XML style is slightly more limited in what it can express than the @AspectJ style: Only the "singleton" aspect instantiation model is supported, and it is not possible to combine named pointcuts declared in XML. For example, in the @AspectJ style you can write something like the following:
-
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样式中,您可以声明前两个连接点:
In the XML style you can declare the first two pointcuts:
<aop:pointcut id="propertyAccess"
expression="execution(* get*())"/>
<aop:pointcut id="operationReturningAnAccount"
expression="execution(com.xyz.Account+ *(..))"/>
XML 方法的缺点是您无法通过组合这些定义来定义 accountPropertyAccess
切入点。
The downside of the XML approach is that you cannot define the
accountPropertyAccess
pointcut by combining these definitions.
@AspectJ 样式支持额外的实例化模型和更丰富的切点组合。它保留切面作为模块化单元的优点。此外,@AspectJ 切面可以同时被 Spring AOP 和 AspectJ 理解(因此也被消费),这也是它的优点之一。所以,如果你后来决定需要 AspectJ 的能力来实现其他需求,你可以轻松迁移到经典的 AspectJ 设置。总体来说,Spring 团队偏好 @AspectJ 样式用于自定义切面,而不是简单的企业服务配置。
The @AspectJ style supports additional instantiation models and richer pointcut composition. It has the advantage of keeping the aspect as a modular unit. It also has the advantage that the @AspectJ aspects can be understood (and thus consumed) both by Spring AOP and by AspectJ. So, if you later decide you need the capabilities of AspectJ to implement additional requirements, you can easily migrate to a classic AspectJ setup. In general, the Spring team prefers the @AspectJ style for custom aspects beyond simple configuration of enterprise services.