AOP切点表达式
Aspectj切入点语法定义
在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点"
例如定义切入点表达式 execution (* com.sample.service.impl..*.*(..))
execution()是最常用的切点函数,其语法如下所示:
整个表达式可以分为五个部分:
1、execution(): 表达式主体。
2、第一个*号:表示返回类型,*号表示所有的类型。
3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
4、第二个*号:表示类名,*号表示所有的类。
5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。
AspectJ的Execution表达式
execution()
execution()是最常用的切点函数,其语法如下所示:
execution(<修饰符模式>? <返回类型模式> <方法名模式>(<参数模式>) <异常模式>?) 除了返回类型模式、方法名模式和参数模式外,其它项都是可选的。与其直接讲解该方法的使用规则,还不如通过一个个具体的例子进行理解。下面,我们给出各种使用execution()函数实例。
1)通过方法签名定义切点
execution(public * *(..))l
匹配所有目标类的public方法,但不匹配SmartSeller和protected void showGoods()方法。第一个*代表返回类型,第二个*代表方法名,而..代表任意入参的方法;
execution(* *To(..))l
匹配目标类所有以To为后缀的方法。它匹配NaiveWaiter和NaughtyWaiter的greetTo()和serveTo()方法。第一个*代表返回类型,而*To代表任意以To为后缀的方法;
2)通过类定义切点
execution(* com.baobaotao.Waiter.*(..))l
匹配Waiter接口的所有方法,它匹配NaiveWaiter和NaughtyWaiter类的greetTo()和serveTo()方法。第一个*代表返回任意类型,com.baobaotao.Waiter.*代表Waiter接口中的所有方法;
execution(* com.baobaotao.Waiter+.*(..))l
匹 配Waiter接口及其所有实现类的方法,它不但匹配NaiveWaiter和NaughtyWaiter类的greetTo()和serveTo()这 两个Waiter接口定义的方法,同时还匹配NaiveWaiter#smile()和NaughtyWaiter#joke()这两个不在Waiter 接口中定义的方法。
3)通过类包定义切点
在类名模式串中,“.*”表示包下的所有类,而“..*”表示包、子孙包下的所有类。
execution(* com.baobaotao.*(..))l
匹配com.baobaotao包下所有类的所有方法;
execution(* com.baobaotao..*(..))l
匹 配com.baobaotao包、子孙包下所有类的所有方法,如com.baobaotao.dao,com.baobaotao.servier以及 com.baobaotao.dao.user包下的所有类的所有方法都匹配。“..”出现在类名中时,后面必须跟“*”,表示包、子孙包下的所有类;
execution(* com..*.*Dao.find*(..))l
匹配包名前缀为com的任何包下类名后缀为Dao的方法,方法名必须以find为前缀。如com.baobaotao.UserDao#findByUserId()、com.baobaotao.dao.ForumDao#findById()的方法都匹配切点。
4)通过方法入参定义切点
切点表达式中方法入参部分比较复杂,可以使用“*”和“ ..”通配符,其中“*”表示任意类型的参数,而“..”表示任意类型参数且参数个数不限。
execution(* joke(String,int)))l
匹 配joke(String,int)方法,且joke()方法的第一个入参是String,第二个入参是int。它匹配 NaughtyWaiter#joke(String,int)方法。如果方法中的入参类型是java.lang包下的类,可以直接使用类名,否则必须使用全限定类名,如joke(java.util.List,int);
execution(* joke(String,*)))l
匹 配目标类中的joke()方法,该方法第一个入参为String,第二个入参可以是任意类型,如joke(String s1,String s2)和joke(String s1,double d2)都匹配,但joke(String s1,double d2,String s3)则不匹配;
execution(* joke(String,..)))l
匹配目标类中的joke()方法,该方法第 一个入参为String,后面可以有任意个入参且入参类型不限,如joke(String s1)、joke(String s1,String s2)和joke(String s1,double d2,String s3)都匹配。
execution(* joke(Object+)))l
匹 配目标类中的joke()方法,方法拥有一个入参,且入参是Object类型或该类的子类。它匹配joke(String s1)和joke(Client c)。如果我们定义的切点是execution(* joke(Object)),则只匹配joke(Object object)而不匹配joke(String cc)或joke(Client c)。
args()和@args()
args()函数的入参是类名,@args()函数的入参必须是注解类的类名。虽然args()允许在类名后使用+通配符后缀,但该通配符在此处没有意义:添加和不添加效果都一样。
1)args()
该函数接受一个类名,表示目标类方法入参对象按类型匹配于指定类时,切点匹配,如下面的例子:
args(com.baobaotao.Waiter)
表 示运行时入参是Waiter类型的方法,它和execution(* *(com.baobaotao.Waiter))区别在于后者是针对类方法的签名而言的,而前者则针对运行时的入参类型而言。如 args(com.baobaotao.Waiter)既匹配于addWaiter(Waiter waiter),也匹配于addNaiveWaiter(NaiveWaiter naiveWaiter),而execution(* *(com.baobaotao.Waiter))只匹配addWaiter(Waiter waiter)方法;实际上,args(com.baobaotao.Waiter)等价于execution(* *(com.baobaotao.Waiter+)),当然也等价于args(com.baobaotao.Waiter+)。
2)@args()
该函数接受一个注解类的类名,当方法的运行时入参对象标注发指定的注解时,方法匹配切点。这个切点函数的匹配规则不太容易理解,我们通过以下示意图对此进行详细讲解:
图 4 @arg(M)匹配示意图(1)
T0、T1、T2、T3具有如图所示的继承关系,假设目标类方法的签名为fun(T1 t),它的入参为T1,而切面的切点定义为@args(M),T2类标注了@M。当fun(T1 t)传入对象是T2或T3时,则方法匹配@args(M)所声明定义的切点;
再看下面的情况,假设方法签名是fun(T1 t),入参对于T1,而标注@M的类是T0,当funt(T1 t)传入T1、T2、T3的实例时,均不匹配切点@args(M)。
图 5 @arg(M)匹配示意图(2)
在类的继承树中,①点为方法签名中入参类型在类继承树中的位置,我们称之为入参类型点,而②为标注了@M注解的类在类继承树中位置,我们称之为注解点。判断方法在运行时是否匹配@agrs(M)切点,可以根据①点和②点在类继承树中的相对位置来判别:
1) 如果在类继承树中注解点②高于入参类型点①,则该目标方法不可能匹配切点@args(M),如图 5所示;
2) 如果在类继承树中注解点②低于入参类型点①,则注解点所在类及其子孙类作为方法入参时,该方法匹配@args(M)切点,如图 4所示。
下 面举一个具体的例子,假设我们定义这样的切点:@args(com.baobaotao.Monitorable) ,如果NaiveWaiter标注了@Monitorable,则对于WaiterManager#addWaiter(Waiter w)方法来说,如果入参是NaiveWaiter或其子类对象,该方法匹配切点,如果入参是NaughtyWaiter对象,不匹配切点。如果 Waiter标注了@Monitorable,但NaiveWaiter未标注@Monitorable,则 WaiterManager#addNaiveWaiter(NaiveWaiter w)却不匹配切点,这是因为注解点(在Waiter)高于入参类型点(NaiveWaiter)。
http://blog.csdn.net/yakoo5/article/details/17001381
AOP切点表达式的更多相关文章
- Spring AOP切点表达式用法总结
1. 简介 面向对象编程,也称为OOP(即Object Oriented Programming)最大的优点在于能够将业务模块进行封装,从而达到功能复用的目的.通过面向对象编程,不同的模 ...
- AspectJ风格的Aop切点表达式
execution(*com.aptech.jb.epet.dao.hibimpl.*.*(..)) 这样写应该就可以了,这是com.aptech.jb.epet.dao.hibimpl 包下所有的类 ...
- 使用注解匹配Spring Aop切点表达式
Spring中的类基本都会标注解,所以使用注解匹配切点可以满足绝大部分需求 主要使用@within()/@target @annotaton() @args()等... 匹配@Service类中的所有 ...
- Spring AOP 切点(pointcut)表达式
这遍文章将介绍Spring AOP切点表达式(下称表达式)语言,首先介绍两个面向切面编程中使用到的术语. 连接点(Joint Point):广义上来讲,方法.异常处理块.字段这些程序调用过程中可以抽像 ...
- SpringBoot AOP中JoinPoint的用法和通知切点表达式
前言 上一篇文章讲解了springboot aop 初步完整的使用和整合 这一篇讲解他的接口方法和类 JoinPoint和ProceedingJoinPoint对象 JoinPoint对象封装了Spr ...
- aop execution 表达式解析
execution(* com.sample.service.impl..*.*(..)) 解释如下: 符号 含义execution()表达式的主体:第一个”*“符号表示返回值的类型任意:com.sa ...
- Spring—切点表达式
摘要: Spring中的AspectJ切点表达式函数 切点表达式函数就像我们的GPS导航软件.通过切点表达式函数,再配合通配符和逻辑运算符的灵活运用,我们能很好定位到我们需要织入增强的连接点上.经过上 ...
- Spring Aop切点
切点用于准确定位应该在什么地方应用切面的通知.通知和切点是切面的最基本的元素.在Spring AOP中要使用AspectJ的切点表达式来定义切点.下面我们列出Spring AOP所支持的AspectJ ...
- 21Spring重用切点表达式
直接看代码: package com.cn.spring.aop.impl; //加减乘除的接口类 public interface ArithmeticCalculator { int add(in ...
随机推荐
- HttpClient传递Cookie
使用代码访问http资源,我们通常用WebRequest,当然,HttpClient提供了更方便的封装,我用得更多.只是碰到一些需要(cookie)鉴权的情况,需要把cookie伴随请求一起发到服务器 ...
- JS的事件冒泡和事件捕获
先上结论:他们是描述事件触发时序问题的术语.事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件.相反的,事件冒泡是自下而上的去触发事件.绑定事件方法的第三个参数,就是控制事件 ...
- jquery计算出left和top,让一个div水平垂直居中的简单实例
if($("#cont1").css("position")!="fixed"){ $("#cont1" ...
- WPF: 把引用的dll移动到自定义路径
需求: 有A.exe和B.exe, 都引用了 C.dll, output路径都是 W:\Debug. A和B都添加了对C的引用,正常情况下C会被复制到 output 里面. C这样子的dll很多,不想 ...
- ASP工程文件(csproj)解读
https://blog.csdn.net/austin_link/article/details/40596185 C#项目中都会有一个不起眼的文件,后缀名csproj,很多人都会忽视它.其实,这个 ...
- STL 源代码剖析 算法 stl_algo.h -- search_n
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie search_n ------------------------------------- ...
- 添加app第一次启动页面
一.添加几个成员变量 @interface hDisplayView ()<UIScrollViewDelegate> { UIScrollView *_bigScrollView; NS ...
- laravel 使用验证码
1)php.ini需要开两个扩展 extension=php_fileinfo.dllextension=php_gd2.dll 2)使用composer安装类包 composer require m ...
- NGUI在5.3打包失败问题
一.NGUI版本 NGUI是很好用的Unity UI插件. 当前使用版本NGUI Next-Gen UI v3.9.7 (Feb 10, 2016)和NGUI Next-Gen UI 3.9.0两个版 ...
- Nutch 使用总结
Nutch 是一个开源Java 实现的搜索引擎.它提供了我们运行自己的搜索引擎所需的全部工具.包括全文搜索和Web爬虫. Nutch使用方法简介: http://blog.csdn.net/pengp ...