183

我的印象是 Spring AOP 最适合用于特定于应用程序的任务,例如安全性、日志记录、事务等,因为它使用自定义 Java5 注释作为框架。然而,AspectJ 似乎对设计模式更友好。

谁能强调在 Spring 应用程序中使用 Spring AOP 与 AspectJ 的各种优缺点?

4

8 回答 8

255

Spring-AOP 优点

  • 它比 AspectJ 更易于使用,因为您不必使用 LTW(加载时编织)或 AspectJ 编译器。

  • 它使用代理模式和装饰器模式

Spring-AOP 缺点

  • 这是基于代理的 AOP,所以基本上你只能使用方法执行连接点。
  • 在同一个类中调用另一个方法时不应用方面。
  • 可能会有一点运行时开销。
  • Spring-AOP 不能向不是由 Spring 工厂创建的任何内容添加方面

AspectJ 优点

  • 这支持所有连接点。这意味着你可以做任何事情。
  • 运行时开销比 Spring AOP 少。

方面的缺点

  • 当心。检查您的方面是否仅编织到您想要编织的内容。
  • 您需要使用 AspectJ 编译器进行额外的构建过程,或者必须设置 LTW(加载时编织)
于 2009-10-22T12:10:01.377 回答
22

附加说明:如果高负载下的性能很重要,您将需要比 Spring AOP 快 9-35 倍的 AspectJ。10ns vs 355ns 听起来可能不多,但我见过人们使用很多方面。10K的价值的方面。在这些情况下,您的请求可能涉及数千个方面。在这种情况下,您将 ms 添加到该请求中。

请参阅基准

于 2014-02-16T01:28:02.027 回答
21

除了其他人所说的 - 只是换个说法,there are two major differences

  1. 一是与织造的类型有关。
  2. 另一个连接点定义。

Spring-AOP:使用代理的概念进行运行时编织dynamic proxy if interface exists or cglib library if direct implementation provided.

AspectJ:编译时编织,AspectJ Java Tools(ajc compiler)如果源可用或编译后编织(使用编译文件)。此外,可以启用 Spring 的加载时间编织 - 它需要aspectj定义文件并提供灵活性。

编译时编织可以提供性能(在某些情况下)以及joinpoint definition in Spring-aop is restricted to method definition only which is not the case for AspectJ.

于 2009-10-30T10:01:50.163 回答
18

弹簧用户手册会给出很多信息,直接从马嘴里说出来。

6.4 章 - 选择使用哪种 AOP 声明风格对你来说已经死了,因为它讨论了两者的优缺点。

6.1.2 节 - Spring AOP 功能和目标以及第 6.2 章- @Aspect 支持6.8 - 将 AspectJ 与 Spring 应用程序一起使用应该特别有趣。

于 2009-10-29T07:21:54.060 回答
14

Spring AOP 是 Spring 框架的重要组成部分之一。在非常基础的阶段,spring 框架是基于 IoC 和 AOP 的。在 Spring 的官方课程中有一张幻灯片,上面写着:

AOP 是框架中最重要的部分之一。

理解 Spring 中的 AOP 是如何工作的关键点是,当您使用 Spring 编写 Aspect 时,我们会通过为您的对象构建代理来检测框架,JDKDynamicProxy如果您的 bean 实现了接口,或者如果您的 bean 没有实现任何接口,则通过 CGLIB界面。请记住,如果您使用 Spring 3.2 之前的版本,则您的类路径中必须包含 cglib 2.2。从 Spring 3.2 开始,它是无用的,因为 cglib 2.2 包含在核心中。

bean 创建时的框架将创建一个代理,该代理包装您的对象并添加横切关注点职责,例如安全性、事务管理、日志记录等。

以这种方式创建代理将应用于切入点表达式,该表达式对框架进行检测,以决定将创建哪些 bean 和方法作为代理。与您的代码相比,该建议将承担更多责任。请记住,在此过程中,切入点仅捕获未声明为 final 的公共方法。

现在,在 Spring AOP 中,Aspect 的编织将由容器在容器启动时执行,而在 AspectJ 中,您必须通过修改字节码对代码进行后编译来执行此操作。因此,在我看来,Spring 方法比 AspectJ 更简单、更易于管理。

另一方面,使用 Spring AOP,您不能使用 AOP 的全部功能,因为实现是通过代理完成的,而不是通过修改代码来完成的。

与在 AspectJ 中一样,您可以在 SpringAOP 中使用加载时编织。您可以在 spring 中使用代理和特殊配置@EnabledLoadWeaving或在 XML 中实现此功能。您可以使用名称空间作为示例。但是在 Spring AOP 中你不能拦截所有的情况。例如,newSpring AOP 不支持该命令。

aspectof然而,在 Spring AOP 中,您可以通过使用spring 配置 bean 中的工厂方法从 AspectJ 的使用中受益。

由于 Spring AOP 基本上是从容器创建的代理,因此您只能将 AOP 用于 spring bean。在使用 AspectJ 时,您可以在所有 bean 中使用方面。另一个比较点是调试和代码行为的可预测性。使用 Spring AOP,这项工作全部由 Java 编译器执行,方面是为 Spring bean 创建代理的一种非常酷的方式。在 AspectJ 中,如果您修改代码,则需要更多的编译,并且要了解您的切面在哪里编织可能会很困难。即使在 spring 中关闭编织也更简单:使用 spring 从配置中删除方面,重新启动它就可以工作了。在 AspectJ 中,您必须重新编译代码!

在加载时编织中,AspectJ 比 Spring 更灵活,因为 Spring 不支持 AspectJ 的所有选项。但在我看来,如果您想更改 bean 的创建过程,更好的方法是在工厂中管理自定义登录,而不是在加载时编织改变新操作员行为的方面。

希望这篇AspectJ和Spring AOP的全景图能帮助大家理解这两种药水的区别

于 2016-03-10T22:04:11.697 回答
1

这篇文章也对该主题有很好的解释。

Spring AOP 和 AspectJ 有不同的目标。

Spring AOP 旨在跨 Spring IoC 提供一个简单的 AOP 实现,以解决程序员面临的最常见问题。

另一方面,AspectJ 是独创的 AOP 技术,旨在提供完整的 AOP 解决方案。

于 2019-01-28T13:37:04.377 回答
0

重要的是要考虑你的方面是否是关键任务以及你的代码部署在哪里。Spring AOP 意味着您依赖于加载时编织。这可能无法编织,并且根据我的经验,这意味着可能存在记录的错误,但不会阻止应用程序在没有方面代码的情况下运行案子; 但我个人并不知道]。编译时编织避免了这种情况。

此外,如果您将 AspectJ 与 aspectj-maven-plugin 结合使用,那么您可以在 CI 环境中针对您的方面运行单元测试,并确信构建的工件经过测试和正确编织。虽然您当然可以编写 Spring 驱动的单元测试,但您仍然不能保证部署的代码将是在 LTW 失败时测试过的代码。

另一个考虑因素是您是否将应用程序托管在能够直接监控服务器/应用程序启动成功或失败的环境中,或者您的应用程序是否部署在不受您监督的环境中[例如由客户托管]。同样,这将为编译时间编织指明方向。

五年前,我更倾向于使用 Spring 配置的 AOP,原因很简单,因为它更容易使用并且不太可能破坏我的 IDE。然而,随着计算能力和可用内存的增加,这已不再是一个问题,并且基于我上面概述的原因,带有 aspectj-maven-plugin 的 CTW 在我的工作环境中已成为更好的选择。

于 2018-01-25T21:47:31.183 回答
0

与 AOP 相比,AspectJ 不需要在编译时增强目标类。相反,它在运行时为目标类生成一个代理类,它要么实现与目标类相同的接口,要么是目标类的子类。

总之,代理类的实例可以用作目标类的实例。一般来说,编译时增强的 AOP 框架在性能上更有优势——因为运行时增强的 AOP 框架每次运行时都需要动态增强。

于 2019-10-21T07:19:13.880 回答