AOP简单应用(一)-execution篇
前言
AOP,简单的说就是面向切面编程。什么叫面向切面呢?举个简单的例子,比如说你要给所有的click事件添加一个避免连续点击的功能,方法很简单,写完后放到一个工具类中,然后事件中调用,触发连续点击了就return掉。那么在这个过程中有几个问题需要注意:第一,需要在所有的点击事件中添加,有想法的朋友们可能会说我可以抽象出一个已经实现该方法的类出来,以后点击事件都实现这个类就好了。但这个协议你需要告知所有的开发人员,让他们遵守才行。第二:难免会有漏掉的地方,而且排查起来也非常麻烦。第三:假如后续不需要这个功能了,删除的过程也会让人疯狂。那么AOP就可以简单的实现,而不需要去侵入到业务层代码,只需要知道我要面向的功能--点击事件--这个切面就ok了,针对这个切面的内容,再进行下一步的处理,然后在编译的过程中,会自动将处理的代码编译到每一个点击事件中,完全无侵入的实现功能。
集成
本篇主要讲解Aspectj,Github地址:点我。
集成分两步步:
- 第一步,在工程目录下的gradle中添加:
classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.1'
- 第二步,在app的gradle添加:
apply plugin: 'android-aspectjx'
,并引用implementation 'org.aspectj:aspectjrt:1.8.13'
,编译后即可使用Aspectj了。
图2
图3
切入点指示符
切入点指示符是用来指示切入点表达式的目的,有大概以下几种:
- execution:用于匹配方法执行的连接点;
- within:用于匹配指定类型内的方法执行;
- this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配;
- target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;
- args:用于匹配当前执行的方法传入的参数为指定类型的执行方法;
- @within:用于匹配所以持有指定注解类型内的方法;
- @target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解;
- @args:用于匹配当前执行的方法传入的参数持有指定注解的执行;
- @annotation:用于匹配当前执行方法持有指定注解的方法;
- reference pointcut:表示引用其他命名切入点
本篇主要讲解下execution
的语法及其使用方式。
execution切入点
execution是用于匹配方法执行的连接点,换句话说,就是指定我们要hock的点,那么hock的完整写法就是
execution(* android.view.View.OnClickListener.onClick(..))
,直观的看,大致上还是能看的懂是什么意思的。
android.view.View.OnClickListener.onClick(..),这个就比较好理解了,就是指我们要hock的方法的全路径。回头看下回调的onClick方法:
回调是有参数的,那么onClikc(..)
中的..
的意思就是表示我们hock的这个方法是有参数的,那么无参数的hock就不需要写..
了。
*
在Aspect中是通配符,在上面那个例子中,代表的是任意返回值,下面讲解execution语法大家就明白了。
接下来简单的说下execution的语法:
execution(注解?修饰符?返回值类型 类型声明?方法名(参数)异常?)
-
注解:可选,如要hock注解,则必须添加。例如
execution(@java.lang.Override * *(..))
- 修饰符:可选,如public,protected,写在返回值前;
- 返回值类型:必选,可以使用 * 来代表任意返回值;
- 类型声明:可选,可以是任意类型;
- 方法名:必选,可以用*来代表任意方法;
- 参数:()代表是没有参数,(..)代表是匹配任意数量,任意类型的参数,当然也可以指定类型的参数进行匹配,如要接受一个String类型的参数,则(java.lang.String);任意数量的String类型参数:(java.lang.String..);第一个是任意类型,第二个是String的参数匹配:(*,java.lang.String)等等;
-
异常:可选,语法:"throws 任意异常类型",可以是多个,用逗号分隔,例如:throws java.lang.IllegalArgumentException, java.lang.ArrayIndexOutOfBoundsException。
注意:以上所有的类都需要是全类名写入,不能简写