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
Spring AOP 和 AspectJ的更多相关文章
- Spring AOP With AspectJ
一.AOP和拦截器 某些情况下,AOP和拦截器包括Filter能够实现同样的功能,一般都是请求即controller层的操作,这三个执行顺序为Filter>Interceptor>AOP, ...
- Comparing Spring AOP and AspectJ
AOP 概念 在我们开始之前 , 让我们做一个快速.高级别审查的核心术语和概念 : 方面 — —标准 / 特征代码被分散在多个场所中的应用 , 通常不同于实际的业务逻辑 (例如 , 交易管理) .各方 ...
- 比较 Spring AOP 与 AspectJ
本文翻译自博客Comparing Spring AOP and AspectJ(转载:https://juejin.im/post/5a695b3cf265da3e47449471) 介绍 如今有多个 ...
- 比较分析 Spring AOP 和 AspectJ 之间的差别
面向方面的编程(AOP) 是一种编程范式,旨在通过允许横切关注点的分离,提高模块化.AOP提供方面来将跨越对象关注点模块化.虽然现在可以获得许多AOP框架,但在这里我们要区分的只有两个流行的框架:Sp ...
- Spring aop与AspectJ的区别?
根据我看spring官方文档的理解(不出意外是最正确的答案): ①选择spring的AOP还是AspectJ? spring确实有自己的AOP.功能已经基本够用了,除非你的要在接口上动态代理或者方法拦 ...
- spring aop与aspectj
AOP:面向切面编程 简介 AOP解决的问题:将核心业务代码与外围业务(日志记录.权限校验.异常处理.事务控制)代码分离出来,提高模块化,降低代码耦合度,使职责更单一. AOP应用场景: 日志记录.权 ...
- 曹工说Spring Boot源码(22)-- 你说我Spring Aop依赖AspectJ,我依赖它什么了
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- Spring错误——Spring AOP——org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException
背景:学习切面,测试前置通知功能,xml配置如下 <?xml version="1.0" encoding="UTF-8"?> <beans ...
- spring---aop(10)---Spring AOP中AspectJ
写在前面 在之前的文章中有写到,Spring在配置中,会存在大量的切面配置.然而在很多情况下,SpringAOP 所提供的切面类真的不是很够用,比如想拦截制定的注解方法,我们就必须扩展DefalutP ...
随机推荐
- windows下mongodb基础玩法系列二CURD附加一
windows下mongodb基础玩法系列 windows下mongodb基础玩法系列一介绍与安装 windows下mongodb基础玩法系列二CURD操作(创建.更新.读取和删除) windows下 ...
- Java中的静态变量、静态方法问题
由关键字static所定义的变量与方法,分别称为静态变量和静态方法,它们又都被称为静态成员 1.静态方法 无需本类的对象也可以调用此方法,调用形式为“类名.方法名”,静态方法常常为其他类提供一些方法而 ...
- MySQL 事务机制
事务处理是保证数据安全的重要机制,事务有四个重要属性 ,根据它们的英文名称可以记为ACID: 原子性(Atomic): 事务操作是不可分割的; 事务只存在已执行和未执行两种状态,不存在只执行了部分指令 ...
- SpringMVC+SpringJdbc+SQLServer+EasyUI增删改查
前言 前天用SpringJdbc连接了一把SQLServer,早上起来用SpringMVC+SpringJdbc+EasUI写了个增删改查的demo,主要是熟悉下SpringMVC相关知识点,如vie ...
- .6-浅析webpack源码之validateSchema模块
validateSchema模块 首先来看错误检测: const webpackOptionsValidationErrors = validateSchema(webpackOptionsSchem ...
- Morley's Therorem(UVA11178+几何)
题意:Morley定理,求D.E.F的坐标 思路:没什么算法,就是几何的应用.注意旋转角就好了. 转载请注明出处:寻找&星空の孩子 题目链接:UVA11178 #include<cstd ...
- Python带你轻松进行网页爬虫
前不久DotNet开源大本营通过为.NET程序员演示如何在.NET下使用C#+HtmlAgilityPack+XPath进行网页数据的抓取,从而为我们展示了HtmlAgilitypack利器的优点和使 ...
- ArrayList 原码解析
基于java1.71.ArrayList 是基于数组实现的 通过源码 我们可以知道 ArrayList 提供了三种构造器用于实例化 /** * Constructs an empty list wit ...
- 【pygame游戏编程】第四篇-----打字测速游戏
下面我们一起用pygame编写一个打字测速游戏 这是一个很实用的有趣的小游戏: 开始之前先来学习几个小函数: 1. ord(ch) python内置函数,传入一个字符,返回字符的ascii码 2.ch ...
- 2017-10-29 用中文命名API的意义和途径
"中文编程"知乎专栏原链 在前文对在代码中使用中文命名的质疑与回应中阐述了在代码中使用中文命名的益处. 此文将从软件使用者的角度阐述对API中文化的意义并探讨实现途径. 当然, 文 ...