Spring AOP 和 AspectJ 的比较

简介: Spring AOP 和 AspectJ 的比较

一、简介

如今有多个可用的 AOP 库,这些库需要能够回答许多问题:

  • 它与我现有的或新的应用程序兼容吗?
  • 哪里可以实现AOP?
  • 它与我的应用程序集成的速度有多快?
  • 性能开销是多少?

在本文中,我们将回答这些问题并介绍 Spring AOP 和 AspectJ——两个最流行的 Java AOP 框架。

2.AOP概

在开始之前,让我们对术语和核心概念进行快速、高层次的回顾:

  • 方面 – 分散在应用程序中多个位置的标准代码/功能,通常与实际业务逻辑(例如事务管理)不同。每个方面都侧重于特定的横切功能
  • 连接点——它是程序执行过程中的一个特定点,例如方法执行、构造函数调用或字段赋值
  • 建议 – 方面在特定连接点采取的操作
  • 切入点——匹配连接点的正则表达式。每次任何连接点与切入点匹配时,都会执行与该切入点关联的指定建议
  • 编织——将方面与目标对象链接起来以创建建议对象的过程

3. Spring AOP和AspectJ现在,让我们从多个方面来讨论 Spring AOP 和 AspectJ,例如功能、目标、编织、内部结构、连接点和简单性。

3.1. 能力和目标

简单地说,Spring AOP 和 AspectJ 有不同的目标。

Spring AOP 旨在提供跨 Spring IoC 的简单 AOP 实现,以解决程序员面临的最常见问题。它并不是一个完整的 AOP 解决方案——它只能应用于由 Spring 容器管理的 bean。

另一方面,AspectJ是原始的AOP技术,旨在提供完整的AOP解决方案。它比 Spring AOP 更健壮,但也复杂得多。还值得注意的是,AspectJ 可以应用于所有域对象。

3.2. 编织

AspectJ 和 Spring AOP 都使用不同类型的编织,这会影响它们在性能和易用性方面的行为。

AspectJ 使用三种不同类型的编织:

  1. 编译时编织:AspectJ 编译器将方面和应用程序的源代码作为输入,并生成编织类文件作为输出
  2. 编译后编织:这也称为二进制编织。它用于将现有的类文件和 JAR 文件与我们的方面编织在一起
  3. 加载时编织:这与之前的二进制编织完全相同,不同之处在于编织被推迟,直到类加载器将类文件加载到 JVM

有关 AspectJ 本身的更多深入信息,请阅读本文

正如 AspectJ 使用编译时和类加载时编织一样,Spring AOP 使用运行时编织

通过运行时编织,各个方面在应用程序执行期间使用目标对象的代理进行编织 - 使用 JDK 动态代理或 CGLIB 代理(在下一点中讨论):

3.3. 内部结构及应用

Spring AOP是一个基于代理的AOP框架。这意味着要实现目标对象的方面,它将创建该对象的代理。这是通过以下两种方式之一实现的:

  1. JDK动态代理——Spring AOP的首选方式。每当目标对象实现一个接口时,就会使用 JDK 动态代理
  2. CGLIB代理——如果目标对象没有实现接口,则可以使用CGLIB代理

我们可以从官方文档中了解更多关于Spring AOP代理机制的信息

另一方面,AspectJ 在运行时不执行任何操作,因为类是直接使用方面编译的。

因此与 Spring AOP 不同,它不需要任何设计模式。为了将方面编织到代码中,它引入了称为 AspectJ 编译器 (ajc) 的编译器,通过它我们可以编译程序,然后通过提供一个小型(< 100K)运行时库来运行它。

3.4. 连接点

在3.3节中,我们展示了Spring AOP是基于代理模式的。因此,它需要对目标 Java 类进行子类化并相应地应用横切关注点。

但它有一个限制。我们不能在“最终”类之间应用横切关注点(或方面),因为它们无法被覆盖,因此会导致运行时异常。

这同样适用于静态和最终方法。Spring 方面不能应用于它们,因为它们不能被覆盖。因此,Spring AOP 由于这些限制,仅支持方法执行连接点。

然而,AspectJ 在运行之前将横切关注点直接编织到实际代码中。与 Spring AOP 不同,它不需要子类化目标对象,因此也支持许多其他连接点。以下是支持的连接点的摘要:

连接点 Spring AOP 支持 支持 AspectJ
方法调用 是的
方法执行 是的 是的
构造函数调用 是的
构造函数执行 是的
静态初始化器执行 是的
对象初始化 是的
现场参考 是的
现场作业 是的
处理程序执行 是的
建议执行 是的

还值得注意的是,在 Spring AOP 中,方面并不应用于同一类中调用的方法。

这显然是因为当我们调用同一个类中的方法时,我们并没有调用 Spring AOP 提供的代理的方法。如果我们需要这个功能,那么我们必须在不同的bean中定义一个单独的方法,或者使用AspectJ。

3.5. 简单

Spring AOP 显然更简单,因为它没有在我们的构建过程之间引入任何额外的编译器或编织器。它使用运行时编织,因此它与我们通常的构建过程无缝集成。虽然它看起来很简单,但它只适用于由 Spring 管理的 bean。

但是,要使用 AspectJ,我们需要引入 AspectJ 编译器 (ajc) 并重新打包所有库(除非我们切换到编译后或加载时编织)。

当然,这比前者更复杂——因为它引入了 AspectJ Java 工具(其中包括编译器(ajc)、调试器(ajdb)、文档生成器(ajdoc)、程序结构浏览器(ajbrowser))需要与我们的 IDE 或构建工具集成。

3.6. 表现就性能而言,编译时编织比运行时编织快得多Spring AOP是一个基于代理的框架,因此在应用程序启动时会创建代理。此外,每个方面还有更多的方法调用,这会对性能产生负面影响。

另一方面,AspectJ 在应用程序执行之前将方面编织到主代码中,因此与 Spring AOP 不同,没有额外的运行时开销。

由于这些原因,基准测试表明 AspectJ 几乎比 Spring AOP 快 8 到 35 倍。

4. 总结此快速表总结了 Spring AOP 和 AspectJ 之间的主要区别:

春季AOP 方面J
用纯Java实现 使用Java编程语言的扩展实现
无需单独的编译过程 需要 AspectJ 编译器 (ajc),除非设置了 LTW
仅运行时编织可用 运行时编织不可用。支持编译时、编译后和加载时 Weaving
功能较弱 – 仅支持方法级别编织 更强大——可以编织字段、方法、构造函数、静态初始化器、最终类/方法等……
只能在Spring容器管理的bean上实现 可以在所有域对象上实现
仅支持方法执行切入点 支持所有切入点
代理是由目标对象创建的,方面应用于这些代理 在执行应用程序之前(运行时之前),方面直接编织到代码中
比 AspectJ 慢很多 更好的性能
易于学习和应用 比 Spring AOP 相对复杂一些

5. 选择正确的框架如果我们分析本节中提出的所有论点,我们将开始理解,并不是一个框架就比另一个框架更好。

简而言之,选择很大程度上取决于我们的要求:

  • 框架:如果应用程序没有使用 Spring 框架,那么我们别无选择,只能放弃使用 Spring AOP 的想法,因为它无法管理 Spring 容器范围之外的任何内容。但是,如果我们的应用程序完全使用 Spring 框架创建,那么我们可以使用 Spring AOP,因为它易于学习和应用
  • 灵活性:鉴于有限的连接点支持,Spring AOP 不是一个完整的 AOP 解决方案,但它解决了程序员面临的最常见问题。尽管如果我们想要更深入地挖掘并最大限度地利用 AOP 并希望获得广泛的可用连接点的支持,那么 AspectJ 是您的选择
  • 性能:如果我们使用有限的方面,那么性能差异很小。但有时应用程序具有超过数万个方面的情况。在这种情况下,我们不想使用运行时编织,因此最好选择 AspectJ。已知 AspectJ 比 Spring AOP 快 8 到 35 倍
  • 两者的优点:这两个框架彼此完全兼容。我们总是可以尽可能利用 Spring AOP,并且仍然使用 AspectJ 来获得前者不支持的连接点的支持

六,结论在本文中,我们在几个关键领域分析了 Spring AOP 和 AspectJ。

我们比较了这两种 AOP 方法的灵活性以及它们与我们的应用程序的配合程度。

目录
相关文章
|
1月前
|
监控 Java 开发者
Spring AOP动态代理
Spring AOP动态代理
43 1
|
1月前
|
Java Spring 容器
Spring的AOP失效场景详解
Spring的AOP失效场景详解
114 0
|
2月前
|
XML Java 编译器
Spring AOP初步理解及使用
Spring AOP初步理解及使用
49 0
|
2月前
|
Java Spring
[Spring]aop的配置与使用
[Spring]aop的配置与使用
40 0
[Spring]aop的配置与使用
|
30天前
|
设计模式 Java Maven
Spring Aop 底层责任链思路实现-springaopdi-ceng-ze-ren-lian-si-lu-shi-xian
Spring Aop 底层责任链思路实现-springaopdi-ceng-ze-ren-lian-si-lu-shi-xian
35 1
|
2月前
|
XML Java 数据格式
5个点轻松搞定Spring AOP底层实现原理
AOP 也是 Spring 中一个较为重要的内容,相对于传统的 OOP 模式,AOP 有很多让人难以理解的地方,本篇文章将向大家介绍 AOP 的实现方法及其底层实现,内容包括:
47 1
|
24天前
|
XML Java Maven
Spring之Aop的注解使用
Spring之Aop的注解使用
|
29天前
|
Java Spring
Spring 如何实现 AOP
Spring 如何实现 AOP
17 0
|
1月前
|
Java Spring
【spring(三)】AOP总结
【spring(三)】AOP总结
|
1月前
|
Java 开发者 Spring
Spring AOP精讲
Spring AOP精讲
24 0