Spring AOP vs AspectJ

zot*_*guy 174 java spring design-patterns aspectj spring-aop

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

任何人都可以强调在Spring应用程序中使用Spring AOP和AspectJ的各种优缺点吗?

Whi*_*hip 231

Spring-AOP优点

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

  • 它使用Proxy模式和Decorator模式

Spring-AOP Cons

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

AspectJ专业人士

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

AspectJ Cons

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

  • @Configurable需要通过Spring使用AspecJ.从文档:`如果您需要建议不由Spring容器管理的对象(通常是域对象),那么您将需要使用AspectJ. (18认同)
  • @Moreaki:作为一个骗子,他说"有点开销",作为职业选手,他说'开销很小'.单个"a"差异非常重要 - 在英语中,"一点"意味着"一些",而"一点"意味着"几乎没有". (15认同)
  • 另一个对我来说是一个不可思议的长栈,因为基于代理的方法 (7认同)
  • 这不正确@Configurable允许这样做 (4认同)
  • 答案中令人困惑的部分:一个工具的运行时间开销如何是专业的,而另一个工具的运行时间开销很小? (2认同)
  • “当心。” 不是一个骗局。 (2认同)

tec*_*zen 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.


elh*_*oim 18

弹簧用户手册将直接从马的口中提供大量信息.

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

6.1.2节 - Spring AOP功能和目标和章节6.2 - @Aspect支持6.8 - 在Spring应用程序中使用AspectJ应该特别有趣.


Jos*_*ust 18

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

查看基准.

  • 基准测试,请访问https://web.archive.org/web/20150520175004/https://docs.codehaus.org/display/AW/AOP+Benchmark (3认同)

Val*_*udi 12

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

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

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

bean创建的框架将创建一个包装对象的代理,并添加交叉关注的职责,如安全性,事务管理,日志记录等.

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

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

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

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

但是在Spring AOP中,您可以通过aspectof在spring配置bean中使用工厂方法来使用AspectJ .

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

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

我希望AspectJ和Spring AOP的全景可以帮助你理解两种魔药的区别