AOP 学习笔记-总括

概述

AOP(Aspect Orient Programming,面向切面),作为OOP(面向对象编程思想)的补充。OOP 引入封装,继承,多态概念来建立一种对象或类的层次结构,用来模拟具有层次关系的对象的公共行为的集合。但是当我们需要为分散或者没有关联的对象引入公共行为的时候,OOP 则无能为力。例如日志功能,往往水平的分布于所有对象的功能中。这些代码一般和核心业务逻辑无关,在 OOP 设计中又会造成大量的代码重复,不利于各个模块的重用。

AOP 利用“横切”技术,把这些影响多个类的公共行为封装到一个可重用模块中,叫做“Aspect”。使用“横切”技术,AOP 将软件系统分为两个部分:核心关注点和横切关注点。 简单的说业务处理的主要流程就是核心关注点,与业务关系不大的部分就是横切关注点,它们经常出现在核心关注点附近,而各处都基本相似。

AOP 主要用在以下场景:

  • Authentication 权限
  • Transactions 事务
  • logging, tracing, profiling and monitoring 记录跟踪 优化 校准
  • Caching 缓存
  • Lazy loading 懒加载
  • Error handling 错误处理
  • Persistence 持久化
  • Resource pooling 资源池
  • Debugging 调试

等等

核心概念

  • Aspect

“横切”技术抽象,对多个类的公共行为的封装。包含横切关注点,如对哪些方法进行拦截,拦截后如何处理,类似于 OOP 中的 class。

  • Joinpoint

程序的执行点,例如一个方法的执行或者对异常的处理。

  • Advice

在特定的连接点,AOP框架执行的动作.前置/后置/例外/最终/环绕通知(调用方法之前执行,全部执行完毕之后)

  • Pointcut

定义规则,让 AOP 框架明白对哪些 Joinpoint 进行拦截。

  • Introduction

添加方法或字段到增强(Adviced)的类

  • Target Object

代理的目标对象,也就是执行核心关注点的对象。

  • AOP Proxy

增强后的对象,也就是在核心关注点周围增加了横切关注点的对象

  • Weaving

将 Aspect 关联到 Target Object 后生成 AOP Proxy 对象的过程。这个过程可以在编译时进行,比如使用 AspectJ 编译器,也可以在类加载时和运行时中。Spring AOP 是在运行时进行这个过程的。

下图是使用 Spring AOP 和 @AspectJ 标注的代码:

图1 example

@Aspect 标注表明 FenceProcessor 类是一个 Aspect,在它中定义了 Advice 和 Pointcut 等关注点。

@Before 标注表明了方法 before 是一个前置 Advice,该参数传入 Joinpoint 对象,可以使用 Joinpoint 获取 Target Object 和 Method。注意下 @Before 标注中的 value:

execution(@(com.youguo.tool.fence.annotation.Fence) * *(..))

这个是用了 AspectJ 切入点语法,代表了 Pointcut,定义了那么方法需要被拦截。

Spring AOP

考虑到实际应用中,Spring 作为经典的 IOC 容器已经深入人心,大大小小的项目几乎都会使用 Spring 来管理对象。所以在选择 AOP 框架的时候,考虑到与Spring IOC 之间的良好兼容,以及易用的特性,第一个想到的就是 Spring AOP。

Spring AOP 是用纯 Java 实现的,所以它并不需要在编译阶段进行特殊处理,它是在运行时关联 Aspect,所以也不要控制类加载的层次,所以它可以很好兼容 Servlet 容器 和应用服务器。Spring AOP不同于大多数其他 AOP 框架。Spring AOP 的目的并不是为了提供最完整的AOP实现(虽然Spring AOP具有相当的能力),而是提供一个AOP实现与Spring IOC之间的紧密集成。也就是说 Spring AOP 仅用于 Spring Beans 的横切(增强)。如果是普通的 POJO,则 Spring AOP 就无能为力了。

VS Aspectj

Aspectj 是一种基于 Java 的面向切面编程语言,兼容 Java 平台。和 Spring AOP 不同,AspectJ 属于静态 weave,它有自己的语法和编译器 ajc,不能使用 JDK 原生编译器。易用性和可理解上要比 Spring AOP 差,但是性能上要更胜一筹,而且 AspectJ 提供了完整的 AOP 实现。

当选择 AOP 框架时,总结下主要还是考虑以下几点:

  • 增强对象是否只是 Spring Bean

Spring AOP 只支持 Spring Bean 增强,使用 AspectJ 你可以在任何 Java 对象上应用通知,而不需要在任何文件中创建或配置任何 bean。

  • 简单易用

Spring AOP 只支持运行时 Weaving,而 AspectJ 支持 编译时 Weaving。AspectJ 需要使用 acj 编译代码,并要学习相关语法,虽然简单,但是 Spring AOP 更易用。

@AspectJ 标注

在图 1 的代码中,我们就使用了 @AspectJ 标注,这种标注最先是 AspectJ 框架引入并使用的,包含在 AspectJ 5 中。为了与 AspectJ 框架区分,所以加上了 @ 代表注解。为了代替传统的 XML 配置,Spring AOP 使用了和 AspectJ 5 一摸一样的注解,同时使用了 AspectJ 的模块来解析和匹配这些注解。所以 Spring AOP 依赖于 AspectJ 的包:

org.aspectj.aspectjweaver
org.aspectj.aspectjrt

这也导致很多人误解 Spring AOP 是以 AspectJ 为增加实现方式。然而并不是,Spring AOP 还是基于 JDK动态代理或 CGLib,并没有依赖于 AspejctJ 编译器和织入器(weaver)。

如果要开启 @AsepctJ,若是用 XML 配置,则添加:

<aop:aspectj-autoproxy/>

若是用注解配置,则添加 @EnableAspectJAutoProxy:

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {

}

鉴于篇幅,具体的标注和 Pointcut,有机会另外总结一篇。

JDK 动态代理 VS CGLIB

动态代理相对于静态代理而言。代理模式实现如下图所示,如果我们使用静态代理,那么对于同一个目标类,要实现不同的前置/后置处理,需要定义不同的代理类,这会产生非常多的类,产生较多重复代码,编程也相对繁琐。

图2 代理模式实现
JDK 动态代理

JDK 动态代理将增强功能进行抽象:

  1. 代理类实现 InvocationHandler.invoke 接口实现增强功能
  2. 调用 Proxy.newProxyInstance(ClassLoader loader,Class<?>[] instance, InvocationHandler h) 获得代理对象,instance 一般是一组接口
  3. 通过 Proxy 对象,调用代理方法。

JDK 动态代理有如下缺陷:

  1. 被代理对象必须基于接口;
  2. 通过反射来动态代理方法,消耗系统性能。

Spring AOP 默认使用 JDK 动态代理实现。

CGLIB

CGLIB(Code Generation Library)它是一个代码生成类库。它可以在运行时候动态是生成某个类的子类。CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM(Java字节码操控框架),来转换字节码并生成新的类。因为是通过继承生成子类来增强功能,所以 final 修饰的类就不能通过 CGLIB 生成代理。

CGLib 实现动态代理需要引入 cglib jar 包:

<dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2.2</version>
</dependency>

操作基本步骤如下:

  1. 代理类实现 MethodInterceptor.intercept 进行增强
  2. 生成 Enhancer 对象,传入代理类对象,调用 create 生成代理对象
  3. 通过代理对象,调用代理方法。

CGLib 动态代理有如下优缺点:

  1. 被代理类不需要基于接口
  2. 通过生成字节码实现,比反射快那么一点点。
  3. cglib会继承被代理类,需要重写被代理方法,所以被代理类不能是final类,被代理方法不能是final。

Spring AOP 使用 CGLib 实现,需进行如下配置:

<aop:aspectj-autoproxy proxy-target-class="true"/>

思维脑图

网上看到一张非常好的思维脑图,特纪录:

图3 AOP 思维脑图

内容来源

https://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html

http://www.cnblogs.com/xrq730/p/4919025.html

http://www.jianshu.com/p/fe8d1e8bd63e

http://blog.csdn.net/zl3450341/article/details/7673938

https://my.oschina.net/huangyong/blog/161338

https://my.oschina.net/huangyong/blog/161402

https://www.oschina.net/translate/comparative_analysis_between_spring_aop_and_aspectj

http://www.eclipse.org/aspectj/

http://www.cnblogs.com/fillPv/p/5939277.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 在理解Spring AOP以及理清它与Aspect和cglib之间关系之前,有很多基础工作要做,比如,先对代理模式...
    maxwellyue阅读 1,179评论 0 5
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • 基本知识 其实, 接触了这么久的 AOP, 我感觉, AOP 给人难以理解的一个关键点是它的概念比较多, 而且坑爹...
    永顺阅读 8,082评论 5 114
  • 团队开发框架实战—面向切面的编程 AOP 引言 软件开发的目标是要对世界的部分元素或者信息流建立模型,实现软件系统...
    Bobby0322阅读 4,130评论 4 49
  • AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横...
    dolphin叔叔阅读 34,467评论 7 90