现如今有许多个可用的 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

Spring AOP 和 AspectJ的更多相关文章

  1. Spring AOP With AspectJ

    一.AOP和拦截器 某些情况下,AOP和拦截器包括Filter能够实现同样的功能,一般都是请求即controller层的操作,这三个执行顺序为Filter>Interceptor>AOP, ...

  2. Comparing Spring AOP and AspectJ

    AOP 概念 在我们开始之前 , 让我们做一个快速.高级别审查的核心术语和概念 : 方面 — —标准 / 特征代码被分散在多个场所中的应用 , 通常不同于实际的业务逻辑 (例如 , 交易管理) .各方 ...

  3. 比较 Spring AOP 与 AspectJ

    本文翻译自博客Comparing Spring AOP and AspectJ(转载:https://juejin.im/post/5a695b3cf265da3e47449471) 介绍 如今有多个 ...

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

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

  5. Spring aop与AspectJ的区别?

    根据我看spring官方文档的理解(不出意外是最正确的答案): ①选择spring的AOP还是AspectJ? spring确实有自己的AOP.功能已经基本够用了,除非你的要在接口上动态代理或者方法拦 ...

  6. spring aop与aspectj

    AOP:面向切面编程 简介 AOP解决的问题:将核心业务代码与外围业务(日志记录.权限校验.异常处理.事务控制)代码分离出来,提高模块化,降低代码耦合度,使职责更单一. AOP应用场景: 日志记录.权 ...

  7. 曹工说Spring Boot源码(22)-- 你说我Spring Aop依赖AspectJ,我依赖它什么了

    写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...

  8. Spring错误——Spring AOP——org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException

    背景:学习切面,测试前置通知功能,xml配置如下 <?xml version="1.0" encoding="UTF-8"?> <beans ...

  9. spring---aop(10)---Spring AOP中AspectJ

    写在前面 在之前的文章中有写到,Spring在配置中,会存在大量的切面配置.然而在很多情况下,SpringAOP 所提供的切面类真的不是很够用,比如想拦截制定的注解方法,我们就必须扩展DefalutP ...

随机推荐

  1. Linux 服务器命令,持续更新……

    记录一下常用命令给自己备忘备查,会持续更新-- 一.查看和修改Linux的时间 1. 查看时间和日期,命令: date 2.设定时间和日期 例如:将系统日期修改成2020年2月14日12点的命令: d ...

  2. 【转】java String.split()函数的用法分析

      在java.lang包中有String.split()方法的原型是: public String[] split(String regex, int limit) split函数是用于使用特定的切 ...

  3. oracle用户权限

    权限: create session create table unlimited tablespace connect resource dba 例: #sqlplus /nolog SQL> ...

  4. T-SQL:开窗函数(十二)

    1.基本概念 开窗函数分为两个部分分别是 1.聚合,排名,偏移,分布函数 . 2.开窗分区,排序,框架. 下面举个例子 SELECT empid, ordermonth, val, SUM(val) ...

  5. 菜鸟入门【ASP.NET Core】12:JWT 设计解析及定制

    前言 上一节我们讲述的书如何使用jwt token,而且上一节的token是要加Authorization:bearer XXXXXXXXXXXX才能访问. 这一节我们来研究如何自定义类似jwt的to ...

  6. Java并发编程:什么是CAS?这回总算知道了

    无锁的思想 众所周知,Java中对并发控制的最常见方法就是锁,锁能保证同一时刻只能有一个线程访问临界区的资源,从而实现线程安全.然而,锁虽然有效,但采用的是一种悲观的策略.它假设每一次对临界区资源的访 ...

  7. 【Spring】10、Spring中用@Component、@Repository、@Service和 @Controller等标注的默认Bean名称会是小写开头的非限定类名

    @Service用于标注业务层组件(我们通常定义的service层就用这个) @Controller用于标注控制层组件(如struts中的action) @Repository用于标注数据访问组件,即 ...

  8. WCF Service 转换为Web Service 中字段属性

    1.新建WCF服务,服务中包含对象 2.部署WCF服务,并将其转换为应用程序 3.通过添加服务引用,使用WCF服务 4.调用对应的对象时需要对应的值设置为True. 参考:https://cloud. ...

  9. css iphonex适配

    /*  iphonex适配 */ @media only screen and (device-width:375px) and (-webkit-device-pixel-ratio: 3) { . ...

  10. What I am concerned about

    redux: https://www.cnblogs.com/XieJunBao/p/9232341.html vuex: https://juejin.im/post/5a8eb24e6fb9a06 ...