zoukankan      html  css  js  c++  java
  • 【AOP】Spring AOP 和 AspectJ

    现如今有许多个可用的 AOP 库,使用这些库需要能够回答以下问题:

    是否与现有的或新的应用程序兼容?

    在哪里可以使用 AOP ?

    如何迅速与应用程序集成?

    性能开销是多少?

    在本文中,我们将回答这些问题并介绍 Spring AOP 和 AspectJ ——两个最受欢迎的 AOP 框架。

    AOP 概念

    在我们开始之前,让我们对术语和核心概念进行快速复习:

    Aspect - 分散在应用程序中的多个位置的标准代码/功能,通常与实际的业务逻辑(例如事务管理)不同。 每个切面都侧重于具体的交叉切割功能。

    Joinpoint – 它是在执行方法、构造函数调用或字段分配等过程时特定的点。

    Advice – 在具体 Joinpoint 切面执行通知。

    Pointcut –与 Joinpoint 匹配的正则表达式。 每次任何 Joinpoint 与 Pointcut 匹配时,将执行与该 Pointcut 相关联的指定的通知。

    Weaving –把切面应用到目标对象来创建新的 advised 对象的过程。

    Spring AOP 和 AspectJ

    现在,我们通过一些数据来讨论 Spring AOP 和 AspectJ ,例如性能、目标、织入、内部结构、连接点和易用性。

    目标

    简单来说,Spring AOP 和 AspectJ 有不同的目标。

    Spring AOP 旨在为 Spring IoC 提供一个简单的 AOP 实现,以解决程序员面临的最常见的问题。 它不是一个完整的 AOP 解决方案 - 它只能应用于由 Spring 容器管理的 Bean 。

    另一方面, AspectJ 是原始的 AOP 技术,旨在提供完整的 AOP 解决方案。 它比 Spring AOP 更强大,但也更复杂。 还值得注意的是, AspectJ 可以跨所有域对象应用。

    织入

    AspectJ 和 Spring AOP 都使用了不同类型的会影响他们在性能和易用性方面行为的 Weaving。

    AspectJ 使用三种不同类型的 Weaving :

    Compile-time Weaving:AspectJ 编译器将我们切面的源代码和应用程序作为输入,生成已经织入的类文件作为输出。

    Post-compile Weaving:这也称为二进制 Weaving。它与我们的切面用于编写现有的类文件和 JAR 文件。

    Load-time Weaving:这与前面的二进制织入完全一样,区别在于类加载器将类文件加载到 JVM 时,Weaving 被推迟。

    有关 AspectJ 本身的更多详细信息,请转到http://www.baeldung.com/rest-with-spring-course#certification-class。

    AspectJ 使用编译时和类载入时 Weaving,Spring AOP 使用运行时 Weaving。

    使用运行时织入,在使用目标对象的代理程序执行应用程序期间使用 JDK 动态代理或 CGLIB 代理(下文将讨论)进行织入:

    内部结构与应用

    Spring AOP 是一个基于代理的 AOP 框架。 这意味着为了实现目标对象的切面,它将创建该对象的代理对象。 这是通过以下两种方法之一实现的:

    1、JDK 动态代理 : Spring AOP 的首选方式。 只要目标对象实现了一个接口,那么将使用 JDK 动态代理。

    2、CGLIB 代理 : 如果目标对象未实现接口,则可以使用 CGLIB 代理。

    我们可以从官方文档中了解更多关于 Spring AOP 代理机制的信息。

    另一方面,AspectJ 在运行时没有做任何事情,因为类是直接用切面编译的。

    和 Spring AOP 不同,它不需要任何设计模式。 为了编写代码的切面,它将其编译器称为 AspectJ 编译器(ajc),通过它来编译我们的程序,然后通过提供一个小的(<100K)运行时库来运行它。

    Joinpoints

    从上面的内容来看,我们发现 Spring AOP 是基于代理模式的。 因此,它需要对目标 Java 类进行子类化,并相应地应用交叉问题。

    但它有一个限制, 我们不能跨越 “final” 的类交叉关注(或方面),因为它们不能被覆盖,因此会导致运行时异常。

    这同样适用于 Static 和 Final 方法。 Spring 切面无法应用它们,因为它们不能被覆盖。 因此 Spring AOP 因为这些限制,只支持方法执行连接点。

    然而,AspectJ 在运行之前将交叉切合的问题直接编写到实际的代码中。与 Spring AOP 不同,它不需要对目标对象进行子类化,因此也支持许多其他连接点。 以下是支持的 Joinpoint 的摘要:

    值得注意的是,在 Spring AOP 中,切面不适用于在同一类中调用的方法。

    这显然是因为当我们在同一个类中调用一个方法时,我们不会调用 Spring AOP 提供的代理方法。 如果我们需要这个功能,那么我们必须在不同的 bean 中定义一个单独的方法,或者使用 AspectJ。

    易用性

    Spring AOP 显然更简单,因为在我们的构建过程之间不会引入任何额外的编译器或者 weaver 。 它使用运行时织入,因此它与我们通常的构建过程无缝集成。 虽然看起来很简单,但它只适用于由 Spring 管理的 bean 。

    然而,要使用 AspectJ ,我们需要引入 AspectJ 编译器(ajc)并重新打包所有的库(除非我们切换到后期编译或加载时织入)。

    这当然比前者更复杂 - 因为它引入了 AspectJ Java 工具(其中包括一个编译器(ajc),一个调试器(ajdb),一个文档生成器(ajdoc),一个程序结构浏览器(ajbrowser)),我们 需要与我们的IDE或构建工具集成。

    性能

    就性能而言,编译时织入比运行时织入快得多。 Spring AOP 是一个基于代理的框架,因此在应用程序启动时创建代理。 此外,每个切面还有一些方法调用,这会对性能产生负面影响。

    另一方面, AspectJ 在应用程序执行之前将这些切面编入主代码,因此与 Spring AOP 不同,没有额外的运行时开销。

    由于这些原因,基准测试表明 AspectJ 比 Spring AOP 快8到35倍。

    比较

    本快速表总结了 Spring AOP 和 AspectJ 之间的主要区别:

    选择正确的框架

    如果我们分析本节中提出的所有论据,我们将开始明白,一个框架并不比另一个框架更好。

    简单地说,选择在很大程度上取决于我们的需求:

    框架:如果应用程序不使用 Spring 框架,那么我们别无选择,只能放弃使用 Spring AOP 的想法,因为它无法管理任何超出 Spring 容器范围的东西。但是,如果我们的应用程序是完全使用 Spring 框架创建的,那么我们可以使用 Spring AOP 来直接学习和应用。

    灵活性:由于连接点支持有限,Spring AOP 不是一个完整的 AOP 解决方案,而是解决了程序员面临的最常见的问题。所以如果我们想深入挖掘和利用 AOP 的最大功能,并希望得到广泛的可用连接点的支持,那么就选 AspectJ。

    性能:如果我们使用有限的切面,那么就有微不足道的性能差异。但有时候,一个应用程序有几万个切面。在这种情况下,我们不想使用运行时织入,因此最好选择 AspectJ 。已知 AspectJ 比 Spring AOP 快8到35倍。

    两者兼有:这两个框架都是完全兼容的。我们可以随时利用 Spring AOP ,并且仍然使用 AspectJ 获得前者不支持的连接点的支持。

    原文:https://blog.csdn.net/wangqingjiewa/article/details/78456072 

  • 相关阅读:
    [ios] 响应上下左右滑动手势
    [ios]字符串转化成NSDate类型 计算与当前时间的相差 月数 天数 【转】
    [ios] NSSet,NSMutableSet[zhuan]
    [ios] 如何让xcode自动检查内存泄露 【转】
    iOS 使用Quartz 2D画虚线 【转】
    [ios]设置表格单元格交替背景 【转】
    [ios] IOS文件操作的两种方式:NSFileManager操作和流操作【转】
    [ios] 自定义UIAlertView样式,实现可替换背景和按钮 【转】
    [ios]上传应用程序到app store 【转】
    [ios] iOS中arc的设置与使用
  • 原文地址:https://www.cnblogs.com/itplay/p/10018826.html
Copyright © 2011-2022 走看看