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

时间: 2024-11-03 22:09:42

AOP切点表达式的相关文章

Spring Aop 切点表达式

在Spring AOP 中,通常需要借助AspectJ 的切点表达式语言来定义切点.重要的是Spring 中仅支持AspectJ切点指示器的一个子集. Spring 支持的AspectJ的切点指示器 AspectJ 指示器 描述 args() 限制连接点匹配参数为执行类型的执行方法 @args() 限制连接点匹配参数由执行注解标注的执行方法 execution() 匹配连接点的执行方法 this() 限制连接点匹配AOP代理的Bean引用类型为指定类型的Bean target() 限制连接点匹配

Spring AOP切点表达式用法总结

1. 简介 面向对象编程,也称为OOP(即Object Oriented Programming)最大的优点在于能够将业务模块进行封装,从而达到功能复用的目的.通过面向对象编程,不同的模板可以相互组装,从而实现更为复杂的业务模块,其结构形式可用下图表示: 面向对象编程解决了业务模块的封装复用的问题,但是对于某些模块,其本身并不独属于摸个业务模块,而是根据不同的情况,贯穿于某几个或全部的模块之间的.例如登录验证,其只开放几个可以不用登录的接口给用户使用(一般登录使用拦截器实现,但是其切面思想是一致

AspectJ风格的Aop切点表达式

execution(*com.aptech.jb.epet.dao.hibimpl.*.*(..)) 这样写应该就可以了,这是com.aptech.jb.epet.dao.hibimpl 包下所有的类的所有方法. 第一个*代表所有的返回值类型 第二个*代表所有的类 第三个*代表类所有方法 最后一个..代表所有的参数. Spring AOP 用户可能会经常使用 execution切入点指示符.执行表达式的格式如下: execution(modifiers-pattern? ret-type-pat

使用注解匹配Spring Aop切点表达式

Spring中的类基本都会标注解,所以使用注解匹配切点可以满足绝大部分需求 主要使用@within()/@target @annotaton() @args()等... 匹配@Service类中的所有方法: @within(org.springframework.stereotype.Service) 或 @target(org.springframework.stereotype.Service) 匹配标注了@RequestMapping的所有方法 @annotation(org.spring

Spring AOP 切点(pointcut)表达式

这遍文章将介绍Spring AOP切点表达式(下称表达式)语言,首先介绍两个面向切面编程中使用到的术语. 连接点(Joint Point):广义上来讲,方法.异常处理块.字段这些程序调用过程中可以抽像成一个执行步骤(或者说执行点)的单元.从Spring AOP来讲,就是指java的方法和异常处理代码块. 切点(Pointcut):是连接点的描述定义,Spring AOP通过切点来定位到哪些连接点.切点表达式语言就是切点用来定义连接点的语法. 切点指示符 切点指示符是切点定义的关键字,切点表达式以

切点表达式定义了拦截类中所有方法,所以每个方法都被增强

1.AOP的作用 在OOP中,正是这种分散在各处且与对象核心功能无关的代码(横切代码)的存在,使得模块复用难度增加.AOP则将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可重用的模块,这个模块被命名为"切面"(Aspect),切面将那些与业务无关,却被业务模块共同调用的逻辑提取并封装起来,减少了系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性. 2.DI 和 IOC 概念 依赖注入或控制反转的定义中,调用者不负责被调用者的实例创建工作,该工作

Other - 04 - AspectJ学习笔记 - 切点表达式

SourceAnalysis - 50 - Spring - AspectJ 这篇的目的也比较直接,今天突然发现同事问到切点表达式发现自己还是不太熟悉 AspectJ 的切点表达式,只知道最简单的 execution 表达式,所以来整理一下一些切点表达式的使用方法,算是插入的一篇文章吧. 首先对于一个切点 pointcut 来说,它分为两个核心部分,第一部分是 joinpoint,第二部分是 pointcut.而切点本身的作用是选择需要被横切的逻辑块,而 before / after 等是 ad

21Spring重用切点表达式

直接看代码: package com.cn.spring.aop.impl; //加减乘除的接口类 public interface ArithmeticCalculator { int add(int i, int j); int sub(int i, int j); int mul(int i, int j); int div(int i, int j); } package com.cn.spring.aop.impl; import org.springframework.stereot

必备技能:spring aop 切入点表达式,你都会么?

本文主要介绍spring aop中9种切入点表达式的写法 execute within this target args @target @within @annotation @args 1.execute表达式 拦截任意公共方法 execution(public * *(..)) 拦截以set开头的任意方法 execution(* set*(..)) 拦截类或者接口中的方法 execution(* com.xyz.service.AccountService.*(..)) 拦截Account