怎么理解spring ioc和aop(比较SpringAOP)
怎么理解spring ioc和aop(比较SpringAOP)Aspect - 分散在应用程序中的多个位置的标准代码/功能,通常与实际的业务逻辑(例如事务管理)不同。 每个切面都侧重于具体的交叉切割功能。在我们开始之前,让我们对术语和核心概念进行快速复习:性能开销是多少?在本文中,我们将回答这些问题并介绍 Spring AOP 和 AspectJ ——两个最受欢迎的 AOP 框架。AOP 概念
现如今有许多个可用的 AOP 库,使用这些库需要能够回答以下问题:
-
是否与现有的或新的应用程序兼容?
-
在哪里可以使用 AOP ?
-
如何迅速与应用程序集成?
-
性能开销是多少?
在本文中,我们将回答这些问题并介绍 Spring AOP 和 AspectJ ——两个最受欢迎的 AOP 框架。
AOP 概念
在我们开始之前,让我们对术语和核心概念进行快速复习:
Aspect - 分散在应用程序中的多个位置的标准代码/功能,通常与实际的业务逻辑(例如事务管理)不同。 每个切面都侧重于具体的交叉切割功能。
Joinpoint – 它是在执行方法、构造函数调用或字段分配等过程时特定的点。
Advice – 在具体 Joinpoint 切面执行通知。
Pointcut –与 Joinpoint 匹配的正则表达式。 每次任何 Joinpoint 与 Pointcut 匹配时,将执行与该 Pointcut 相关联的指定的通知。
Weaving –把切面应用到目标对象来创建新的 advised 对象的过程。
Spring AOP 和 AspectJ
内部结构与应用
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 获得前者不支持的连接点的支持。
结论
在本文中,我们分析了 Spring AOP 和 AspectJ 在几个关键领域。
我们比较了 AOP 的两种方法,灵活性以及它们如何轻松地适应我们的应用程序。
原文链接:http://www.baeldung.com/spring-aop-vs-aspectj
作者: 王志宇
JFrog 中国研发工程师,曾在唯品会担任研发工程师,擅长Java,参与过多个互联网平台的研发和运维工作,现专注于Devops 落地,持续集成、持续交付领域。
欢迎转载,但转载请注明作者与出处。谢谢!