首页 文章

Spring AOP vs AspectJ

提问于
浏览
152

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

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

6 回答

  • 201

    Spring-AOP优点

    • 使用它比AspectJ更简单,因为您不必使用LTW(load-time weaving)或AspectJ编译器 .

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

    Spring-AOP Cons

    • 这是基于代理的AOP,所以基本上你只能使用方法执行连接点 .

    • 在同一个类中调用另一个方法时不应用方面 .

    • 可能会有一点运行时开销 .

    • Spring-AOP无法为Spring工厂创建的任何东西添加方面

    AspectJ专业人士

    • 这支持所有连接点 . 这意味着你可以做任何事情 .

    • 运行时开销比Spring AOP少 .

    AspectJ Cons

    • 小心点 . 检查您的方面是否仅编织到您想要编织的部分 .

    • 您需要使用AspectJ Compiler进行额外的构建过程,或者必须设置LTW(加载时编织)

  • 16

    除了其他人所说的 - 只是改写, 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.

  • 21

    附加说明: If performance under high load is important, you'll want AspectJ which is 9-35x faster than Spring AOP . 10ns vs 355ns听起来可能不是很多,但我认为这些方面很重要 . 在这些情况下,您的请求可能涉及数千个方面 . 在这种情况下,您将ms添加到该请求 .

    benchmarks .

  • 17

    The spring user manual将直接从马的口中提供大量信息 .

    因为它讨论了两者的利弊,所以6.4 - Choosing which AOP declaration style to use章对你来说已经死了 .

    段落6.1.2 - Spring AOP Capabilites and goals和章节6.2 - @Aspect support6.8 - Using AspectJ with Spring applications应该特别有趣 .

  • 9

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

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

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

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

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

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

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

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

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

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

相关问题