比较Spring AOP和AspectJ
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使用三种不同的编织方式:
- 编译时编织:AspectJ编译器将方面和应用程序的源代码都作为输入,并生成编织类文件作为输出
- 编译后编织:这也称为二进制编织。它用于与我们的方面编织现有的类文件和JAR文件
- 加载时编织:这与以前的二进制编织完全一样,不同之处在于编织被推迟到类加载器将类文件加载到JVM为止
有关AspectJ本身的更多信息,请继续阅读本文。 由于AspectJ使用编译时和类加载时编织,因此Spring AOP使用运行时编织。 通过运行时编织,可以在应用程序执行期间使用目标对象的代理来编织各方面–使用JDK动态代理或CGLIB代理(将在下一部分中进行讨论):
3.3 内部结构与应用
Spring AOP是基于代理的AOP框架。这意味着要实现目标对象的各个方面,它将创建该对象的代理。这可以通过以下两种方式之一来实现:
- JDK动态代理– Spring AOP的首选方式。每当目标对象实现一个接口时,都将使用JDK动态代理
- 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相关推荐
- 比较Spring AOP与AspectJ
本文翻译自博客Comparing Spring AOP and AspectJ 介绍 如今有多个可用的AOP库,这些组件需要回答一系列的问题: 是否与我现有的应用兼容? 我在哪实现AOP? 集成到我的 ...
- 比较分析 Spring AOP 和 AspectJ 之间的差别
面向方面的编程(AOP) 是一种编程范式,旨在通过允许横切关注点的分离,提高模块化.AOP提供方面来将跨越对象关注点模块化.虽然现在可以获得许多AOP框架,但在这里我们要区分的只有两个流行的框架:Sp ...
- 在 Spring Boot 中使用 Spring AOP 和 AspectJ 来测量方法的执行时间
原文链接:https://dzone.com/articles/logging-average-method-execution-times-via-aspectj 作者:Murat Derman 译 ...
- aopaspect区别_面试官:什么是AOP?Spring AOP和AspectJ的区别是什么?
AOP(Aspect Orient Programming),它是面向对象编程的一种补充,主要应用于处理一些具有横切性质的系统级服务,如日志收集.事务管理.安全检查.缓存.对象池管理等. AOP实现的 ...
- SpringAop与AspectJ的联系与区别____比较分析 Spring AOP 和 AspectJ 之间的差别
SpringAop与AspectJ的联系与区别 区别 AspectJ AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Ja ...
- 框架源码专题:Spring的Aop实现原理,Spring AOP 与 AspectJ 的关系
文章目录 1. Spring AOP 与 AspectJ 的关系 2. JDK和Cglib动态代理的区别 3. Spring AOP应用案例 4. Spring AOP有几种配置方式? 5. Spri ...
- Spring AOP 和 AspectJ的区别
Spring AOP 和 AspectJ的区别 springAOP 是spring支持的面向切面AOP 编程. AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法 ...
- 面试官:说说Spring AOP、AspectJ、CGLIB ?它们有什么关系?
欢迎关注方志朋的博客,回复"666"获面试宝典 AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务 ...
- 面试官:Spring AOP、AspectJ、CGLIB 都是什么鬼?它们有什么关系?
AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理.安全检查.缓存.对象池管理等. AOP 实现的关键就在 ...
最新文章
- Docker 清理命令集锦
- 2020年AI将会如何发展?吴恩达、周志华、Yann LeCun等大神对2020年 AI 发展趋势的预测的预测...
- mysql中以指定字段去重_数据库根据指定字段去重
- 在windows下查看进程
- 读《数字创世纪-人工生命新科学》
- 普通java程序怎样用cron_java – Spring cron vs普通cron?
- setpriority_Java Thread类的最终void setPriority(int priority)方法(带示例)
- 1208. 尽可能使字符串相等
- 官方开源的安卓客户端
- 单片机(ISIS 7 Professional):简易8x8矩阵LED灯代码项目
- java开发规范-控制语句
- 非服务器模式下运行getImageData函数出现 the operation is insecure
- java实现逻辑推断
- PHP+MYSQL实现个人博客网站,PHP动态网页设计
- idea keymap之前选择成 Eclipse 后,idea默认的快捷键Default找不到了的解决办法
- 自己感觉比较不错的美剧(记录自己追剧的岁月)
- 悲观的人更容易获得好的感觉
- openstack上cinder卷的加密
- 记一次组装电脑的经历
- Hadoop安全之Kerberos
热门文章
- linux 扫描mipi设备,VS-RK3399 在linux系统下面调试Mipi camera接口介绍
- java 接口与包_java常用类包接口
- Java ArrayList isEmpty()方法与示例
- scala 获取数组中元素_从Scala中的元素列表中获取随机元素
- 计算机文化基础第二章,计算机文化基础(第二章Windows2000操作系统)
- .net core image怎么保存_轻量级Vue图片上传插件——Vue-core-image-Upload
- 非导向传输媒体| 计算机网络
- 数组copyWithin()方法以及JavaScript中的示例
- HashMap 的 7 种遍历方式与性能分析!「修正篇」
- 设为首页 和 收藏本站js代码 兼容IE,chrome,ff