AOP-AspectJ原理

AspectJ实际上是对AOP编程思想的一个实践。AspectJ提供了一套全新的语法实现,完全兼容Java(其实跟Java之间的区别,只是多了一些关键词而已)。同时,还提供了纯Java语言的实现,通过注解的方式,完成代码编织的功能。因此我们在使用AspectJ的时候有以下两种方式:

  • 使用AspectJ的语言进行开发
  • 通过AspectJ提供的注解在Java语言上开发

因为最终的目的其实都是需要在字节码文件中织入我们自己定义的切面代码,不管使用哪种方式接入AspectJ,都需要使用AspectJ提供的代码编译工具ajc进行编译

JoinPoints
JoinPoints 说明 示例
method call 函数调用 比如调用Log.e(),这是一处Joint point
method execution 函数执行 比如Log.e()的执行内部,是一处Joint Point
constructor call 构造函数调用 与方法的调用类型
constructor executor 构造函数执行 与方法的执行执行
field get 获取某个变量
field set 设置某个变量
static initialization 类初始化
initialization object在构造函数中做的一些工作
handler 异常处理 对应try-catch()中,对应的catch块内的执行

Pointcut使用语法

Pointcut其实是加了筛选条件限制的JoinPoints,而每种类型的JoinPoint都会对应有自己的筛选条件的匹配格式,Pointcut的定义就是要根据不同的JoinPoint声明合适的筛选条件表达式

直接对JoinPoint的选择
JoinPoint类型 Pointcut语法
Method Execution(方法执行) execution(MethodSignature)
Method Call(方法调用) call(MethodSignature)
Constructor Execution(构造器执行) execution(ConstructorSignature)
Construtor Call(构造器调用) call(ConstructorSignature)
Class Initialization(类初始化) staticinitialization(TypeSignature)
Field Read(属性读) get(FieldSignature)
Field Set(属性写) set(FieldSignature)
Exception Handler(异常处理) handler(TypeSignature)
Object Initialization(对象初始化) initialization(ConstructorSignature)
Object Pre-initialization(对象预初始化) preinitialization(ConstructorSignature)
Advice Execution(advice执行) adviceexecution()
  • 在上面表格中所提及到的MethodSignature、ConstructorSignature、TypeSignature、FieldSignature,它们的表达式都可以使用通配符进行匹配。
  • 表格当中的execution、call、set、get、initialization、preinitialization、adviceexecution、staticinitialization这些都是属于AspectJ当中的关键词
  • 表格当中的handler只能与advice中的before(advice的相应关键词及使用参考后文)一起使用
通配符 意义 示例
* 表示除”.”以外的任意字符串 java.*.Date:可以表示java.sql. Date,java.util. Date
.. 表示任意子package或者任意参数参数列表 java..*:表示java任意子包;void getName(..):表示方法参数为任意类型任意个数
+ 表示子类 java..*Model+:表示java任意包中以Model结尾的子类
MethodSignature

定义MethodSignature的条件表达式与定义一个方法类型,其结构如下:

  • 表达式:
    [@注解] [访问权限] 返回值的类型 类全路径名(包名+类名).函数名(参数)
  • 说明:
    1. []当中的内容表示可选项。当没有设定的时候,表示全匹配
    2. 返回值类型、类全路径、函数名、参数都可以使用上面的通配符进行描述。
  • 例子:
    public (..) :表示任意参数任意包下的任意函数名任意返回值的public方法
    @com.example.TestAnnotation com.example..(int) :表示com.example下被TestAnnotation注解了的带一个int类型参数的任意名称任意返回值的方法
ConstructorSignature

Constructorsignature和Method Signature类似,只不过构造函数没有返回值,而且函数名必须叫new.

  • 表达式:
    [@注解] [访问权限] 类全路径名(包名+类名).new(参数)

  • 例子:
    public *..People.new(..) :表示任意包名下面People这个类的public构造器,参数列表任意

FieldSignature

与在类中定一个一个成员变量的格式相类似。

  • 表达式:
    [@注解] [访问权限] 类型 类全路径名.成员变量名

  • 例子:
    String com.example..People.lastName :表示com.example包下面的People这个类中名为lastName的String类型的成员变量

TypeSignature

TypeSignature其实就是用来指定一个类的。因此我们只需要给出一个类的全路径的表达式即可

间接对JoinPoint进行选择

除了上面表格当中提及到的直接对Join Point选择之外,还有一些Pointcut关键字是间接的对Join Point进行选择的。如下表所示:

Pointcut语法 说明 示例
within(TypeSignature) 表示在某个类中所有的Join Point within(com.example.Test):表示在com.example.Test类当中的全部Join Point
withincode(ConstructorSignature/MethodSignature) 表示在某个函数/构造函数当中的Join Point withincode( ..Test(..)):表示在任意包下面的Test函数的所有Join Point
args(TypeSignature) 对Join Point的参数进行条件筛选 args(int,..):表示第一个参数是int,后面参数不限的Join Point

组合Pointcut进行选择

Pointcut之间可以使用“&& | !”这些逻辑符号进行拼接,将两个Pointcut进行拼接,完成一个最终的对JoinPoint的选择操作。(其实就是将上面的间接选择JoinPoint表中关键字定义的Pointcut与直接选择JoinPoint表关键字定义的Pointcut进行拼接)

Advice语法使用

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

推荐阅读更多精彩内容