1. 介绍

当前有多个可用的AOP库,这些库必须能够回答许多问题:

  • 它与我现有的或新的应用程序兼容吗?
  • 在哪里可以实施AOP?
  • 它与我的应用程序集成的速度有多快?
  • 性能开销是多少?

在本文中,我们将着眼于回答这些问题,并介绍Spring AOP和AspectJ(这两种最流行的Java AOP框架)。

2. AOP 概念

在开始之前,让我们对术语和核心概念进行快速的高层次审查:

  • 切面–一种标准代码/功能,分散在应用程序的多个位置,通常与实际的业务逻辑(例如,事务管理)不同。每个方面都专注于特定的跨领域功能
  • 连接点–这是程序执行过程中的特定点,例如方法执行,构造函数调用或字段分配
  • 通知–方面在特定联接点中采取的操作
  • 切入点–与联接点匹配的正则表达式。每当任何连接点与切入点匹配时,都会执行与该切入点关联的指定建议
  • 编织–将方面与目标对象链接以创建建议对象的过程

3.Spring AOP 和AspectJ

现在,让我们从多个角度讨论Spring AOP和AspectJ,例如功能,目标,编织,内部结构,连接点和简单性

3.1 能力和目标

简而言之,Spring AOP和AspectJ具有不同的目标。 Spring AOP旨在在Spring IoC上提供一个简单的AOP实现,以解决程序员面临的最常见问题。它不打算用作完整的AOP解决方案-只能应用于由Spring容器管理的bean。 另一方面,AspectJ是原始的AOP技术,旨在提供完整的AOP解决方案。它比Spring AOP更强大,但也更复杂。还值得注意的是,AspectJ可以应用于所有域对象。

3.2 编织

AspectJ和Spring AOP都使用不同类型的编织,这会影响它们在性能和易用性方面的行为。 AspectJ使用三种不同的编织方式:

  1. 编译时编织:AspectJ编译器将方面和应用程序的源代码都作为输入,并生成编织类文件作为输出
  2. 编译后编织:这也称为二进制编织。它用于与我们的方面编织现有的类文件和JAR文件
  3. 加载时编织:这与以前的二进制编织完全一样,不同之处在于编织被推迟到类加载器将类文件加载到JVM为止

有关AspectJ本身的更多信息,请继续阅读本文。 由于AspectJ使用编译时和类加载时编织,因此Spring AOP使用运行时编织。 通过运行时编织,可以在应用程序执行期间使用目标对象的代理来编织各方面–使用JDK动态代理或CGLIB代理(将在下一部分中进行讨论):

3.3 内部结构与应用

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

  1. JDK动态代理– Spring AOP的首选方式。每当目标对象实现一个接口时,都将使用JDK动态代理
  2. CGLIB代理–如果目标对象未实现接口,则可以使用CGLIB代理

我们可以从官方文档中了解有关Spring AOP代理机制的更多信息。 另一方面,AspectJ在运行时不执行任何操作,因为类是直接用方面编译的。 因此,与Spring AOP不同,它不需要任何设计模式。为了将代码的各个方面编织起来,它引入了称为AspectJ编译器(ajc)的编译器,通过它我们可以编译程序,然后通过提供一个小的(<100K)运行时库来运行它。

3.4 连接点

在3.3节中,我们展示了Spring AOP基于代理模式。因此,它需要对目标Java类进行子类化,并相应地应用跨领域关注点。 但是它有一个局限性。我们不能跨“最终”类应用跨领域关注点(或方面),因为它们不能被覆盖,因此会导致运行时异常。 静态方法和最终方法也是如此。 Spring方面不能应用于它们,因为它们不能被覆盖。因此,由于这些限制,Spring AOP仅支持方法执行连接点。 但是,AspectJ在运行时之前将横切关注点直接编织到实际代码中。与Spring AOP不同,它不需要子类化目标对象,因此也支持许多其他连接点。以下是受支持的连接点的摘要:

Joinpoint Spring AOP Supported AspectJ Supported
Method Call No Yes
Method Execution Yes Yes
Constructor Call No Yes
Constructor Execution No Yes
Static initializer execution No Yes
Object initialization No Yes
Field reference No Yes
Field assignment No Yes
Handler execution No Yes
Advice execution No Yes

还值得注意的是,在Spring AOP中,方面未应用于同一类中调用的方法。 显然,这是因为当我们在同一类中调用方法时,便没有调用Spring AOP提供的代理方法。如果需要此功能,则必须在不同的bean中定义一个单独的方法,或使用AspectJ。

3.5 简单

Spring AOP显然更简单,因为它在构建过程之间没有引入任何额外的编译器或编织器。它使用运行时编织,因此可以与我们通常的构建过程无缝集成。尽管看起来很简单,但是它仅适用于Spring管理的bean。 但是,要使用AspectJ,我们需要引入AspectJ编译器(ajc)并重新打包所有库(除非我们切换到后编译或加载时编织)。 当然,这比前者要复杂得多,因为它引入了AspectJ Java工具(包括编译器(ajc),调试器(ajdb),文档生成器(ajdoc),程序结构浏览器(ajbrowser)),需要与我们的IDE或构建工具集成。

3.6 性能

就性能而言,编译时编织比运行时编织快得多。 Spring AOP是基于代理的框架,因此在应用程序启动时会创建代理。此外,每个方面还有更多方法调用,这会对性能产生负面影响。 另一方面,AspectJ在应用程序执行之前将各方面编织到主代码中,因此与Spring AOP不同,没有额外的运行时开销。 由于这些原因,基准测试表明AspectJ几乎比Spring AOP快8到35倍。

4. 摘要

下表概述了Spring AOP和AspectJ之间的主要区别:

Spring AOP AspectJ
Implemented in pure Java-- 用纯Java实现 Implemented using extensions of Java programming language-- 使用Java编程语言的扩展实现
No need for separate compilation process-- 无需单独的编译过程 Needs AspectJ compiler (ajc) unless LTW is set up-- 除非设置了LTW,否则需要AspectJ编译器(ajc)
Only runtime weaving is available-- 仅需运行时编织 Runtime weaving is not available. Supports compile-time, post-compile, and load-time Weaving-- 运行时编织不可用。支持编译时,后编译和加载时编织
Less Powerful – only supports method level weaving-- 不足–仅支持方法级编织 More Powerful – can weave fields, methods, constructors, static initializers, final class/methods, etc…–更强大–可以编织字段,方法,构造函数,静态初始值设定项,最终类/方法等…
Can only be implemented on beans managed by Spring container-- 只能在Spring容器管理的bean上实现 Can be implemented on all domain objects-- 可以在所有领域对象上实施
Supports only method execution pointcuts-- 仅支持方法执行切入点 Support all pointcuts-- 支持所有切入点
Proxies are created of targeted objects, and aspects are applied on these proxies-- 代理是针对目标对象创建的,并且方面已应用于这些代理 Aspects are weaved directly into code before application is executed (before runtime)–在应用程序执行之前(运行时之前)将方面直接编织到代码中
Much slower than AspectJ-- 比AspectJ慢得多 Better Performance-- 更好的性能
Easy to learn and apply-- 易于学习和应用 Comparatively more complicated than Spring AOP-- 比Spring AOP复杂得多

5. 选择正确的框架

如果我们分析本节中提出的所有论点,就会开始理解,一个框架根本不比另一个框架更好。 简而言之,选择很大程度上取决于我们的要求:

  • 框架:如果应用程序未使用Spring框架,那么我们别无选择,只能放弃使用Spring AOP的想法,因为它无法管理Spring容器无法达到的任何功能。但是,如果我们的应用程序是完全使用Spring框架创建的,那么我们可以使用Spring AOP,因为它易于学习和应用
  • 灵活性:鉴于有限的连接点支持,Spring AOP并不是完整的AOP解决方案,但它解决了程序员面临的最常见问题。尽管如果我们想更深入地挖掘和利用AOP的最大功能,并希望获得广泛的可用连接点的支持,那么AspectJ是一个不错的选择
  • 性能:如果我们使用的方面有限,则性能上将存在微不足道的差异。但是有时在应用程序具有成千上万个方面的情况下。在这种情况下,我们不想使用运行时编织,因此最好选择AspectJ。已知AspectJ比Spring AOP快8到35倍
  • 两者兼有:这两个框架彼此完全兼容。我们总是可以尽可能利用Spring AOP,并且仍然使用AspectJ来获得前者不支持的连接点的支持。

6. 结论

在本文中,我们在几个关键领域分析了Spring AOP和AspectJ。 我们比较了两种AOP方法的灵活性以及它们与我们的应用的适应性。

比较Spring AOP和AspectJ相关推荐

  1. 比较Spring AOP与AspectJ

    本文翻译自博客Comparing Spring AOP and AspectJ 介绍 如今有多个可用的AOP库,这些组件需要回答一系列的问题: 是否与我现有的应用兼容? 我在哪实现AOP? 集成到我的 ...

  2. 比较分析 Spring AOP 和 AspectJ 之间的差别

    面向方面的编程(AOP) 是一种编程范式,旨在通过允许横切关注点的分离,提高模块化.AOP提供方面来将跨越对象关注点模块化.虽然现在可以获得许多AOP框架,但在这里我们要区分的只有两个流行的框架:Sp ...

  3. 在 Spring Boot 中使用 Spring AOP 和 AspectJ 来测量方法的执行时间

    原文链接:https://dzone.com/articles/logging-average-method-execution-times-via-aspectj 作者:Murat Derman 译 ...

  4. aopaspect区别_面试官:什么是AOP?Spring AOP和AspectJ的区别是什么?

    AOP(Aspect Orient Programming),它是面向对象编程的一种补充,主要应用于处理一些具有横切性质的系统级服务,如日志收集.事务管理.安全检查.缓存.对象池管理等. AOP实现的 ...

  5. SpringAop与AspectJ的联系与区别____比较分析 Spring AOP 和 AspectJ 之间的差别

    SpringAop与AspectJ的联系与区别 区别 AspectJ AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Ja ...

  6. 框架源码专题:Spring的Aop实现原理,Spring AOP 与 AspectJ 的关系

    文章目录 1. Spring AOP 与 AspectJ 的关系 2. JDK和Cglib动态代理的区别 3. Spring AOP应用案例 4. Spring AOP有几种配置方式? 5. Spri ...

  7. Spring AOP 和 AspectJ的区别

    Spring AOP 和 AspectJ的区别 springAOP 是spring支持的面向切面AOP 编程. AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法 ...

  8. 面试官:说说Spring AOP、AspectJ、CGLIB ?它们有什么关系?

    欢迎关注方志朋的博客,回复"666"获面试宝典 AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务 ...

  9. 面试官:Spring AOP、AspectJ、CGLIB 都是什么鬼?它们有什么关系?

    AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理.安全检查.缓存.对象池管理等. AOP 实现的关键就在 ...

最新文章

  1. Docker 清理命令集锦
  2. 2020年AI将会如何发展?吴恩达、周志华、Yann LeCun等大神对2020年 AI 发展趋势的预测的预测...
  3. mysql中以指定字段去重_数据库根据指定字段去重
  4. 在windows下查看进程
  5. 读《数字创世纪-人工生命新科学》
  6. 普通java程序怎样用cron_java – Spring cron vs普通cron?
  7. setpriority_Java Thread类的最终void setPriority(int priority)方法(带示例)
  8. 1208. 尽可能使字符串相等
  9. 官方开源的安卓客户端
  10. 单片机(ISIS 7 Professional):简易8x8矩阵LED灯代码项目
  11. java开发规范-控制语句
  12. 非服务器模式下运行getImageData函数出现 the operation is insecure
  13. java实现逻辑推断
  14. PHP+MYSQL实现个人博客网站,PHP动态网页设计
  15. idea keymap之前选择成 Eclipse 后,idea默认的快捷键Default找不到了的解决办法
  16. 自己感觉比较不错的美剧(记录自己追剧的岁月)
  17. 悲观的人更容易获得好的感觉
  18. openstack上cinder卷的加密
  19. 记一次组装电脑的经历
  20. Hadoop安全之Kerberos

热门文章

  1. linux 扫描mipi设备,VS-RK3399 在linux系统下面调试Mipi camera接口介绍
  2. java 接口与包_java常用类包接口
  3. Java ArrayList isEmpty()方法与示例
  4. scala 获取数组中元素_从Scala中的元素列表中获取随机元素
  5. 计算机文化基础第二章,计算机文化基础(第二章Windows2000操作系统)
  6. .net core image怎么保存_轻量级Vue图片上传插件——Vue-core-image-Upload
  7. 非导向传输媒体| 计算机网络
  8. 数组copyWithin()方法以及JavaScript中的示例
  9. HashMap 的 7 种遍历方式与性能分析!「修正篇」
  10. 设为首页 和 收藏本站js代码 兼容IE,chrome,ff