我认为Spring AOP最适合用于特定于应用程序的任务,例如安全性,日志记录,事务等,因为它使用自定义Java5注释作为框架。然而,AspectJ似乎更加友好的设计模式。
任何人都可以强调在Spring应用程序中使用Spring AOP和AspectJ的各种优缺点吗?
答案 0 :(得分:218)
Spring-AOP专业人士
使用它比AspectJ更简单,因为您不必使用LTW(load-time weaving)或AspectJ编译器。
它使用代理模式和装饰器 图案
Spring-AOP Cons
AspectJ专业人士
AspectJ Cons
答案 1 :(得分:21)
除了其他人所说的 - 只是改写一下,there are two major differences
:
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.
答案 2 :(得分:18)
另外需要注意:如果高负载下的性能很重要,那么你需要的AspectJ比Spring AOP快9-35倍。 10ns vs 355ns可能听起来不多,但我见过人们使用很多方面。 10K的方面值得。在这些情况下,您的请求可能涉及数千个方面。在这种情况下,您将ms添加到该请求中。
请参阅benchmarks。
答案 3 :(得分:16)
The spring user manual将直接从马的口中提供大量信息。
章节6.4 - Choosing which AOP declaration style to use对你来说已经死了,因为它讨论了两者的优点和缺点。
段落6.1.2 - Spring AOP Capabilites and goals&章节6.2 - @Aspect support和6.8 - Using AspectJ with Spring applications应该特别有趣。
答案 4 :(得分:12)
Spring AOP是spring框架的重要组成部分之一。在最基本的阶段,spring框架基于IoC和AOP。在Spring的官方课程中,有一张幻灯片,其中说:
AOP是该框架最重要的部分之一。
理解Spring中的AOP如何工作的关键点在于,当您使用Spring编写Aspect时,我们通过为您的对象构建代理来构建框架,如果您的bean实现接口或通过CGLIB,则使用JDKDynamicProxy
如果你的bean没有实现任何接口。请记住,如果您在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中你不能拦截所有的情况。例如,Spring AOP不支持new
命令。
但是在Spring AOP中,您可以通过在spring配置bean中使用aspectof
工厂方法来使用AspectJ。
由于Spring AOP基本上是从容器创建的代理,因此您只能将AOP用于spring bean。使用AspectJ,您可以在所有bean中使用该方面。另一个比较点是调试和代码行为的可预测性。使用Spring AOP,所有工作都是从Java编译器执行的,而方面是为Spring bean创建代理的一种非常酷的方式。在AspectJ中,如果修改代码,则需要进行更多编译并了解编辑方面的位置可能很困难。即使在春天关闭编织也更简单:使用弹簧从配置中删除方面,重新启动并且它可以工作。在AspectJ中,您必须重新编译代码!
在加载时编织中,AspectJ比Spring更灵活,因为Spring不支持AspectJ的所有选项。但在我看来,如果您想要更改bean的创建过程,更好的方法是在工厂中管理自定义登录,而不是使用加载时编织更改新运算符行为的方面。
我希望AspectJ和Spring AOP的全景可以帮助你理解两个魔药的区别
答案 5 :(得分:0)
重要的是要考虑您的方面是否对任务至关重要以及您的代码的部署位置。 Spring AOP意味着您依赖于加载时编织。这可能无法编织,并且根据我的经验意味着可能存在已记录的错误,但不会阻止应用程序在没有方面代码的情况下运行 [我会添加警告,可能有可能以这样的方式配置它情况并非如此;但我个人并不知道]。编译时编织避免了这种情况。
此外,如果您将AspectJ与aspectj-maven-plugin结合使用,那么您可以在CI环境中针对您的方面运行单元测试,并确信已构建的工件经过测试并正确编织。虽然你当然可以编写Spring驱动的单元测试,但你仍然不能保证所部署的代码将是LTW失败时测试的代码。
另一个考虑因素是您是否在一个环境中托管应用程序,在该环境中您可以直接监视服务器/应用程序启动的成功或失败,或者您的应用程序是否部署在不受您监督的环境中[例如由客户托管的地方]。同样,这将指出编译时间编织的方法。
五年前,我更赞成Spring配置的AOP,原因很简单,因为它更容易使用,而且不太可能咀嚼我的IDE。然而,随着计算能力和可用内存的增加,这已成为一个问题,而基于我上面概述的原因,使用aspectj-maven-plugin的CTW已经成为我工作环境中更好的选择。
答案 6 :(得分:0)
此article也对该主题有很好的解释。
Spring AOP和AspectJ具有不同的目标。
Spring AOP旨在为整个Spring提供一个简单的AOP实现 IoC解决了程序员面临的最常见问题。
另一方面,AspectJ是原始的AOP技术,旨在 提供完整的AOP解决方案。
答案 7 :(得分:0)
与AOP相比,AspectJ不需要在编译时增强目标类。相反,它在运行时为目标类生成一个代理类,该代理类要么实现与目标类相同的接口,要么是目标类的子类。
总之,代理类的实例可以用作目标类的实例。通常,编译时增强型AOP框架在性能上更具优势-因为运行时增强的AOP框架每次运行时都需要动态增强。