Spring AOP与AspectJ


178

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

谁能强调在Spring应用程序中使用Spring AOP和AspectJ的利弊吗?


3
当Spring中存在某些注释但Java中也存在注释时,您应该使用什么?Java。相同的逻辑适用于此功能。春天就是春天。今天在这里明天就消失了。(提醒人们在春季之前使用Struts)。AspectJ是首选的长期解决方案。它将比春天持久。在这方面,我并没有解雇Spring,...:-;
INOR

Answers:


235

Spring-AOP优点

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

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

Spring-AOP缺点

  • 这是基于代理的AOP,因此基本上您只能使用方法执行联接点。
  • 在同一类中调用另一个方法时,方面不会应用。
  • 可能会有一点运行时开销。
  • Spring-AOP无法将任何方面添加到Spring工厂未创建的任何内容中

AspectJ专业人士

  • 这支持所有联接点。这意味着您可以做任何事情。
  • 与Spring AOP相比,运行时开销更少。

AspectJ缺点

  • 小心。检查您的方面是否仅编织到想要编织的方面。
  • 您需要使用AspectJ编译器进行额外的构建过程,或者必须设置LTW(加载时编织)

20
@Configurable要求通过Spring使用AspecJ。来自文档:If you need to advise objects not managed by the Spring container (such as domain objects typically), then you will need to use AspectJ.
HDave 2013年

7
对我来说,另一个spring-aop
缺点

1
答案中令人困惑的部分:对于一个工具而言,运行时开销少是一个优点,而对于另一种工具来说,运行时开销却很小呢?
Moreaki

15
@Moreaki:他说“有点开销”是个缺点,而“有点开销”是个优点。单个“ a”差异非常重要-用英语,“一点”表示“一些”,而“一点”表示“几乎没有”。
wujek 2015年

1
只是一个快速的疑问-在您的Spring AOP专家中(第二点)-如果我们在春季使用@Aspect批注,那将是AspectJ AOP,只是想知道在那种情况下它将使用Proxy(运行时)还是字节修改(编译)时间)。因为,我的印象是AspectJ是编译时,而Spring AOP是运行时AOP。请帮助
-Pedantic

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.




14

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

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

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

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

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

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

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

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

但是,在Spring AOP中,可以通过aspectof在spring配置bean中使用factory方法来受益于AspectJ的使用。

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

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

我希望AspectJ和Spring AOP的全景视图可以帮助您了解两种药水的区别


0

重要的是要考虑您的方面是否对任务至关重要,以及代码的部署位置。Spring AOP意味着您将依赖于加载时编织。这可能无法编织,以我的经验,这意味着可能存在已记录的错误,但如果没有方面代码,就不会阻止应用程序运行[我要说明的是,有可能以这种方式配置应用程序,案件; 但我个人并不知道 ]。编译时编织避免了这种情况。

此外,如果将AspectJ与Aspectj-Maven-plugin结合使用,则可以在CI环境中针对您的方面运行单元测试,并且可以确信已对构建的工件进行了测试并正确地进行了编织。虽然可以肯定地编写Spring驱动的单元测试,但仍然不能保证所部署的代码将是LTW失败时所测试的代码。

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

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


0

文章也有关于该主题的一个很好的解释。

Spring AOP和AspectJ具有不同的目标。

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

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


0

与AOP相比,AspectJ无需在编译时增强目标类。而是在运行时为目标类生成代理类,该代理类实现与目标类相同的接口,或者是目标类的子类。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.