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 方法的灵活性以及它们与我们的应用程序的配合程度。

目录
相关文章
|
8天前
|
XML Java 数据安全/隐私保护
Spring Aop该如何使用
本文介绍了AOP(面向切面编程)的基本概念和术语,并通过具体业务场景演示了如何在Spring框架中使用Spring AOP。文章详细解释了切面、连接点、通知、切点等关键术语,并提供了完整的示例代码,帮助读者轻松理解和应用Spring AOP。
Spring Aop该如何使用
|
28天前
|
存储 缓存 Java
Spring高手之路23——AOP触发机制与代理逻辑的执行
本篇文章深入解析了Spring AOP代理的触发机制和执行流程,从源码角度详细讲解了Bean如何被AOP代理,包括代理对象的创建、配置与执行逻辑,帮助读者全面掌握Spring AOP的核心技术。
35 3
Spring高手之路23——AOP触发机制与代理逻辑的执行
|
13天前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
26 1
|
9天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
21 0
|
2月前
|
设计模式 Java 测试技术
spring复习04,静态代理动态代理,AOP
这篇文章讲解了Java代理模式的相关知识,包括静态代理和动态代理(JDK动态代理和CGLIB),以及AOP(面向切面编程)的概念和在Spring框架中的应用。文章还提供了详细的示例代码,演示了如何使用Spring AOP进行方法增强和代理对象的创建。
spring复习04,静态代理动态代理,AOP
|
1月前
|
Java 编译器 Spring
Spring AOP 和 AspectJ 的区别
Spring AOP和AspectJ AOP都是面向切面编程(AOP)的实现,但它们在实现方式、灵活性、依赖性、性能和使用场景等方面存在显著区别。‌
65 2
|
1月前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
【10月更文挑战第1天】Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
126 9
|
1月前
|
XML Java 数据格式
Spring的IOC和AOP
Spring的IOC和AOP
45 0
|
2月前
|
Java 数据库连接 数据库
Spring基础3——AOP,事务管理
AOP简介、入门案例、工作流程、切入点表达式、环绕通知、通知获取参数或返回值或异常、事务管理
Spring基础3——AOP,事务管理
|
3月前
|
XML Java 数据格式
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
这篇文章是Spring5框架的AOP切面编程教程,通过XML配置方式,详细讲解了如何创建被增强类和增强类,如何在Spring配置文件中定义切入点和切面,以及如何将增强逻辑应用到具体方法上。文章通过具体的代码示例和测试结果,展示了使用XML配置实现AOP的过程,并强调了虽然注解开发更为便捷,但掌握XML配置也是非常重要的。
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解