比较分析 Spring AOP 和 AspectJ 之间的差别
|
面向方面的编程(AOP) 是一种编程范式,旨在通过允许横切关注点的分离,提高模块化。AOP提供方面来将跨越对象关注点模块化。虽然现在可以获得许多AOP框架,但在这里我们要区分的只有两个流行的框架:Spring AOP和AspectJ。这里将会帮助你基于一些关键信息,为你的项目选择正确的技术。 Spring AOP不同于大多数其他AOP框架。Spring AOP的目的并不是为了提供最完整的AOP实现(虽然Spring AOP具有相当的能力);而是为了要帮助解决企业应用中的常见问题,提供一个AOP实现与Spring IOC之间的紧密集成。由于Spring AOP是容易实现的,如果你计划在Spring Beans之上将横切关注点模块化,Spring的这一目标将是要点之一。但同样的目标也可能成为一个限制,如果你用的是普通的Java对象而不是Spring beans,并基于此将横切关注点模块化的话。另一方面,AspectJ可用于基于普通Java对象的模块化,但在实施之前需要良好的关于这个主题的知识。 |
|
在决定使用哪种框架实现你的项目之前,有几个要点可以帮助你做出合适的选择(同样适用于其他框架)。 Spring AOP致力于提供一种能够与Spring IoC紧密集成的面向方面框架的实现,以便于解决在开发企业级项目时面临的常见问题。明确你在应用横切关注点(cross-cutting concern)时(例如事物管理、日志或性能评估),需要处理的是Spring beans还是POJO。如果正在开发新的应用,则选择Spring AOP就没有什么阻力。但是如果你正在维护一个现有的应用(该应用并没有使用Spring框架),AspectJ就将是一个自然的选择了。为了详细说明这一点,假如你正在使用Spring AOP,当你想将日志功能作为一个通知(advice)加入到你的应用中,用于追踪程序流程,那么该通知(Advice)就只能应用在Spring beans的连接点(Joinpoint)之上。 |
|
例子:在appbeans.xml中配置如下的切入点(pointcut),那么当调用myServices bean的service方法时就将应用日志通知(advice)。
看一下日志通知将要被应用处的注释,在这里应用程序将记录被调用方法的详细信息。但是,当你在service()方法中调用同一个类中的其他方法时,如果你没有使用代理对象,那么日志通知就不会被应用到这个方法调用上。 例如:
如果你想要在通过this对象调用的方法上应用通知,那么你必须使用currentProxy对象,并调用其上的相应方法。
于此相似,如果你想要在某对象的方法上应用通知,那么你必须使用与该对象相应的Spring bean。
如果你想要应用该通知,那么上述代码必须修改为如下形式。
于此不同,使用“AspectJ”你可以在任何Java对象上应用通知,而不需要在任何文件中创建或配置任何bean。 |
|
另一个需要考虑的因素是,你是希望在编译期间进行织入(weaving),还是编译后(post-compile)或是运行时(run-time)。Spring只支持运行时织入。如果你有多个团队分别开发多个使用Spring编写的模块(导致生成多个jar文件,例如每个模块一个jar文件),并且其中一个团队想要在整个项目中的所有Spring bean(例如,包括已经被其他团队打包了的jar文件)上应用日志通知(在这里日志只是用于加入横切关注点的举例),那么通过配置该团队自己的Spring配置文件就可以轻松做到这一点。之所以可以这样做,就是因为Spring使用的是运行时织入。
如果你使用AspectJ想要做到同样的事情,你也许就需要使用acj(AspectJ编译器)重新编译所有的代码并且进行重新打包。否则,你也可以选择使用AspectJ编译后(post-compile)或载入时(load-time)织入。 |
|
因为Spring基于代理模式(使用CGLIB),它有一个使用限制,即无法在使用final修饰的bean上应用横切关注点。因为代理需要对Java类进行继承,一旦使用了关键字final,这将是无法做到的。 例如,在Spring bean MyServicesImpl上使用关键字final,并配置一个“execution(public * *(..))”这样的切入点,将导致运行时异常(exception),因为Spring不能为MyServicesImpl生成代理。
在这种情况下,你也许会考虑使用AspectJ,其支持编译期织入且不需要生成代理。 于此相似,在static和final方法上应用横切关注点也是无法做到的。因为Spring基于代理模式。如果你在这些方法上配置通知,将导致运行时异常,因为static和final方法是不能被覆盖的。在这种情况下,你也会考虑使用AspectJ,因为其支持编译期织入且不需要生成代理。 |
|
你一定希望使用一种易于实现的方式。因为Spring AOP支持注解,在使用@Aspect注解创建和配置方面时将更加方便。而使用AspectJ,你就需要通过.aj文件来创建方面,并且需要使用ajc(Aspect编译器)来编译代码。所以如果你确定之前提到的限制不会成为你的项目的障碍时,使用Spring AOP。 使用AspectJ的一个间接局限是,因为AspectJ通知可以应用于POJO之上,它有可能将通知应用于一个已配置的通知之上。对于一个你没有注意到这方面问题的大范围应用的通知,这有可能导致一个无限循环。 |
|
例如,创建一个包含如下切入点的方面。
在这种情况下,当proceed即将被调用时,日志通知会被再次应用,这样就导致了嵌套循环。 所以,如果你希望在Spring bean上采取比较简单的方式应用横切关注点时,并且这些bean没有被标以final修饰符,同时相似的方法也没有标以static或final修饰符时,就使用Spring AOP吧。相比之下,如果你需要在所提到的限制之上应用横切关注点,或者要在POJO上应用关注点,那么就使用AspectJ。你也可能选择同时使用两种方法,因为Spring支持这样。 |
比较分析 Spring AOP 和 AspectJ 之间的差别的更多相关文章
- Comparing Spring AOP and AspectJ
AOP 概念 在我们开始之前 , 让我们做一个快速.高级别审查的核心术语和概念 : 方面 — —标准 / 特征代码被分散在多个场所中的应用 , 通常不同于实际的业务逻辑 (例如 , 交易管理) .各方 ...
- 比较 Spring AOP 与 AspectJ
本文翻译自博客Comparing Spring AOP and AspectJ(转载:https://juejin.im/post/5a695b3cf265da3e47449471) 介绍 如今有多个 ...
- Spring AOP 和 AspectJ
现如今有许多个可用的 AOP 库,使用这些库需要能够回答以下问题: 是否与现有的或新的应用程序兼容? 在哪里可以使用 AOP ? 如何迅速与应用程序集成? 性能开销是多少? 在本文中,我们将回答这些问 ...
- 曹工说Spring Boot源码(22)-- 你说我Spring Aop依赖AspectJ,我依赖它什么了
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- Spring AOP With AspectJ
一.AOP和拦截器 某些情况下,AOP和拦截器包括Filter能够实现同样的功能,一般都是请求即controller层的操作,这三个执行顺序为Filter>Interceptor>AOP, ...
- Spring aop与AspectJ的区别?
根据我看spring官方文档的理解(不出意外是最正确的答案): ①选择spring的AOP还是AspectJ? spring确实有自己的AOP.功能已经基本够用了,除非你的要在接口上动态代理或者方法拦 ...
- spring aop与aspectj
AOP:面向切面编程 简介 AOP解决的问题:将核心业务代码与外围业务(日志记录.权限校验.异常处理.事务控制)代码分离出来,提高模块化,降低代码耦合度,使职责更单一. AOP应用场景: 日志记录.权 ...
- spring---aop(10)---Spring AOP中AspectJ
写在前面 在之前的文章中有写到,Spring在配置中,会存在大量的切面配置.然而在很多情况下,SpringAOP 所提供的切面类真的不是很够用,比如想拦截制定的注解方法,我们就必须扩展DefalutP ...
- Spring AOP 基于AspectJ
简介 AspectJ是一个基于Java语言的AOP框架,Spring2.0以后新增了对AspectJ切点表达式支持.因为Spring1.0的时候Aspectj还未出现; AspectJ1.5中新增了对 ...
随机推荐
- Ubuntu Server17.10配置静态IP
今天心血来潮,装个虚拟机Ubuntu打算学点东西,遇到了一些问题,同时借助百度的力量解决了,下面是配置的过程. 一. 安装virtualbox 不知道从哪个版本开始,安装虚拟盒子的时候没有了安装虚拟网 ...
- Spring的属性注入, byName和byType还有注入List属性
昨天花了一晚上的时间又仔细研究了一下Spring的属性注入, 一个新的方法: 自动装载和autowire, 不过因为又想起来老师说不常用, 感觉这一晚上的时间有点亏, 还是自己太愚钝了, 反应太慢 先 ...
- ubuntu安装谷歌拼音输入法
在这篇教程中,我将告诉你如何在ubuntu系统上安装谷歌拼音输入法.谷歌拼音输入法有基于ibus框架的,也有基于fcitx框架的.我只演示fcitx框架下谷歌拼音输入法的安装,因为ibus框架的谷歌拼 ...
- oracle在centos6.5安装
说明 很多操作是默认,具体定制另说. 安装 参考http://www.linuxidc.com/Linux/2014-02/97374p4.htm 这篇是上面那篇的整合版:http://www.cnb ...
- 【校招面试 之 C/C++】第18题 C++ 中的隐式转换以及explicit关键字
1.什么是隐式转换: 众所周知,C++的基本类型中并非完全的对立,部分数据类型之间是可以进行隐式转换的. 所谓隐式转换,是指不需要用户干预,编译器私下进行的类型转换行为.很多时候用户可能都不知道进行了 ...
- mybatis sql语句符号问题
写sql语句<或>不能直接写,而应写作<或>,不然项目不能正常编译启动
- 11-简单解释spingmvc项目的结构
可以简单的理解为下面这样子:
- uploadify 文件上传报http 302错误
uploadify文件上传会报http 302错误,在配置文件中将处理上传的通用类取消验证, 假设上传的通用处理类是fileUpload.ashx,则在配置文件同添加下面过滤配置能解决问题. < ...
- 【笔记】C#往TextBox的方法AppendText加入的内容里插入换行符
C# TextBox换行[huan hang]时你往往会想到直接付给一个含有换行[huan hang]符"\n"的字符[zi fu]串[zi fu chuan]给Text属性[sh ...
- Golang之beego读取配置信息,输出log模块
1,准备好配置文件 [server] listen_ip = "0.0.0.0" listen_port = [logs] log_level=debug log_path=./l ...