面向切面编程(AOP)的理解


Posted in Javascript onMay 01, 2015

在传统的编写业务逻辑处理代码时,我们通常会习惯性地做几件事情:日志记录、事务控制及权限控制等,然后才是编写核心的业务逻辑处理代码。当代码编写完成回头再看时,不禁发现,扬扬洒洒上百行代码中,真正用于核心业务逻辑处理才那么几行,如图6-4所示。方法复方法,类复类,就这样子带着无可奈何遗憾地度过了多少个春秋。这倒也罢,倘若到了项目的尾声,突然决定在权限控制上需要进行大的变动时,成千上万个方法又得一一"登门拜访",痛苦"雪上加霜"。

如果能把图6-4中众多方法中的所有共有代码全部抽取出来,放置到某个地方集中管理,然后在具体运行时,再由容器动态织入这些共有代码的话,最起码可以解决两个问题:

Java EE程序员在编写具体的业务逻辑处理方法时,只需关心核心的业务逻辑处理,既提高了工作效率,又使代码变更简洁优雅。

在日后的维护中由于业务逻辑代码与共有代码分开存放,而且共有代码是集中存放的,因此使维护工作变得简单轻松。

面向切面编程AOP技术就是为解决这个问题而诞生的,切面就是横切面,如图6-5所示,代表的是一个普遍存在的共有功能,例如,日志切面、权限切面及事务切面等。

下面我们以用户管理业务逻辑组件UserService的AOP实现过程(见图6-6)为例,深度剖析一下AOP技术的实现原理。AOP技术是建立在Java语言的反射机制与动态代理机制之上的。业务逻辑组件在运行过程中,AOP容器会动态创建一个代理对象供使用者调用,该代理对象已经按Java EE程序员的意图将切面成功切入到目标方法的连接点上,从而使切面的功能与业务逻辑的功能同时得以执行。从原理上讲,调用者直接调用的其实是AOP容器动态生成的代理对象,再由代理对象调用目标对象完成原始的业务逻辑处理,而代理对象则已经将切面与业务逻辑方法进行了合成。

现将图6-6中涉及到的一些概念解释如下。

切面(Aspect):其实就是共有功能的实现。如日志切面、权限切面、事务切面等。在实际应用中通常是一个存放共有功能实现的普通Java类,之所以能被AOP容器识别成切面,是在配置中指定的。

通知(Advice):是切面的具体实现。以目标方法为参照点,根据放置的地方不同,可分为前置通知(Before)、后置通知(AfterReturning)、异常通知(AfterThrowing)、最终通知(After)与环绕通知(Around)5种。在实际应用中通常是切面类中的一个方法,具体属于哪类通知,同样是在配置中指定的。

连接点(Joinpoint):就是程序在运行过程中能够插入切面的地点。例如,方法调用、异常抛出或字段修改等,但Spring只支持方法级的连接点。

切入点(Pointcut):用于定义通知应该切入到哪些连接点上。不同的通知通常需要切入到不同的连接点上,这种精准的匹配是由切入点的正则表达式来定义的。

目标对象(Target):就是那些即将切入切面的对象,也就是那些被通知的对象。这些对象中已经只剩下干干净净的核心业务逻辑代码了,所有的共有功能代码等待AOP容器的切入。

代理对象(Proxy):将通知应用到目标对象之后被动态创建的对象。可以简单地理解为,代理对象的功能等于目标对象的核心业务逻辑功能加上共有功能。代理对象对于使用者而言是透明的,是程序运行过程中的产物。

织入(Weaving):将切面应用到目标对象从而创建一个新的代理对象的过程。这个过程可以发生在编译期、类装载期及运行期,当然不同的发生点有着不同的前提条件。譬如发生在编译期的话,就要求有一个支持这种AOP实现的特殊编译器;发生在类装载期,就要求有一个支持AOP实现的特殊类装载器;只有发生在运行期,则可直接通过Java语言的反射机制与动态代理机制来动态实现。

以下是补充:

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

AOP与OOP是面向不同领域的两种设计思想。

OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分。

AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。

我们可以单单从上面的字面上来理解AOP和OOP的话,用下面的理解也不为过:

OOP实际上是对对象的属性和行为的封装,而AOP对于这点就无从谈起,但是AOP是处理某个步骤和阶段的,从中进行切面的提取,也就是说,如果几个或更多个逻辑过程中,有重复的操作行为,AOP就可以提取出来,运用动态代理,实现程序功能的统一维护,这么说来可能太含蓄,如果说到权限判断,日志记录等,可能就明白了。如果我们单纯使用OOP,那么权限判断怎么办?在每个操作前都加入权限判断?日志记录怎么办?在每个方法里的开始、结束、异常的地方手动添加日志?所有,如果使用AOP就可以借助代理完成这些重复的操作,就能够在逻辑过程中,降低各部分之间的耦合了。二者扬长补短,互相结合最好。

下面详细了解一些AOP的概念:

•方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。方面用Spring的Advisor或拦截器实现。
•连接点(Joinpoint):程序执行过程中明确的点,如方法的调用或特定的异常被抛出。
•通知(Advice):在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。
•切入点(Pointcut):指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点,例如,使用正则表达式。
•引入(Introduction):添加方法或字段到被通知的类。Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现IsModified接口,来简化缓存。
•目标对象(Target Object):包含连接点的对象,也被称作被通知或被代理对象。
•AOP代理(AOP Proxy):AOP框架创建的对象,包含通知。在Spring中,AOP代理可以是JDK动态代理或CGLIB代理。
•编织(Weaving):组装方面来创建一个被通知对象。这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。

Spring 中 AOP 代理由 Spring 的 IoC 容器负责生成、管理,其依赖关系也由 IoC 容器负责管理。至于Spring的AOP在项目中具体是怎么实现的,下篇博客会以日志记录为例进行学习。

Javascript 相关文章推荐
js写一个弹出层并锁屏效果实现代码
Dec 07 Javascript
怎么选择Javascript框架(Javascript Framework)
Nov 22 Javascript
javascript实现瀑布流自适应遇到的问题及解决方案
Jan 28 Javascript
jquery显示隐藏元素的实现代码
May 19 Javascript
微信小程序左滑删除效果的实现代码
Feb 20 Javascript
AngularJS constant和value区别详解
Feb 28 Javascript
VUE axios发送跨域请求需要注意的问题
Jul 06 Javascript
JavaScript Drum Kit 指南(纯 JS 模拟敲鼓效果)
Jul 23 Javascript
webpack 模块热替换原理
Apr 09 Javascript
jQuery动态移除与增加onclick属性的方法详解
Jun 07 jQuery
在Vue mounted方法中使用data变量详解
Nov 05 Javascript
uni-app自定义导航栏按钮|uniapp仿微信顶部导航条功能
Nov 12 Javascript
yui3的AOP(面向切面编程)和OOP(面向对象编程)
May 01 #Javascript
使用AOP改善javascript代码
May 01 #Javascript
Javascript aop(面向切面编程)之around(环绕)分析
May 01 #Javascript
jQuery插件Zclip实现完美兼容个浏览器点击复制内容到剪贴板
Apr 30 #Javascript
jQuery插件slider实现拖动滑块选取价格范围
Apr 30 #Javascript
javascript实现验证身份证号的有效性并提示
Apr 30 #Javascript
PHP+jQuery实现随意拖动层并即时保存拖动位置
Apr 30 #Javascript
You might like
检测png图片是否完整的php代码
2010/09/06 PHP
php中利用str_pad函数生成数字递增形式的产品编号
2013/09/30 PHP
php字符串按照单词进行反转的方法
2015/03/14 PHP
PHP、Java des加密解密实例
2015/04/27 PHP
使用PHP+AJAX让WordPress动态加载文章的教程
2015/12/11 PHP
PHP安装memcache扩展的步骤讲解
2019/02/14 PHP
Asp.net下使用Jquery Ajax传送和接收DataTable的代码
2010/09/12 Javascript
关于COOKIE个数与大小的问题
2011/01/17 Javascript
说明你的Javascript技术很烂的五个原因
2011/04/26 Javascript
DOM事件阶段以及事件捕获与事件冒泡先后执行顺序(图文详解)
2015/08/18 Javascript
jquery获取css的color值返回RGB的方法
2015/12/18 Javascript
在Mac OS上安装使用Node.js的项目自动化构建工具Gulp
2016/06/18 Javascript
谈谈JavaScript的New关键字
2016/08/26 Javascript
js文件中直接alert()中文出来的是乱码的解决方法
2016/11/01 Javascript
原生js实现轮播图的示例代码
2017/02/20 Javascript
JavaScript定时器setTimeout()和setInterval()详解
2017/08/18 Javascript
深入理解ES6学习笔记之块级作用域绑定
2017/08/19 Javascript
element-ui组件中input等的change事件中传递自定义参数
2019/05/22 Javascript
详解vuex的简单todolist例子
2019/07/14 Javascript
详解vue 组件的实现原理
2020/11/12 Javascript
[48:45]Ti4 循环赛第二日 NEWBEE vs EG
2014/07/11 DOTA
[03:15]2014DOTA2国际邀请赛 专访国士无双信心满满
2014/07/12 DOTA
python str与repr的区别
2013/03/23 Python
听歌识曲--用python实现一个音乐检索器的功能
2016/11/15 Python
Python自定义装饰器原理与用法实例分析
2018/07/16 Python
python 批量修改/替换数据的实例
2018/07/25 Python
使用OpenCV实现仿射变换—平移功能
2019/08/29 Python
HTML5新增的表单元素和属性实例解析
2014/07/07 HTML / CSS
台湾乐天市场:日本No.1的网路购物网站
2017/03/22 全球购物
英国综合网上购物商城:The Hut
2018/07/03 全球购物
学生自我鉴定模板
2013/12/30 职场文书
会计学生自我鉴定
2014/02/06 职场文书
2014年政工师工作总结
2014/12/18 职场文书
SQL语句中JOIN的用法场景分析
2021/07/25 SQL Server
「我的青春恋爱物语果然有问题。-妄言录-」第20卷封面公开
2022/03/21 日漫
Redis 哨兵机制及配置实现
2022/03/25 Redis