springboot aop的execution 表达式详解

Aspectj切入点语法定义java

 

在使用spring框架配置AOP的时候,无论是经过XML配置文件仍是注解的方式都须要定义pointcut"切入点"spring

例如定义切入点表达式  execution (* com.sample.service.impl..*.*(..))框架

execution()是最经常使用的切点函数,其语法以下所示:函数

 整个表达式能够分为五个部分:this

 一、execution(): 表达式主体。代理

 二、第一个*号:表示返回类型,*号表示全部的类型。对象

 三、包名:表示须要拦截的包名,后面的两个句点表示当前包和当前包的全部子包,com.sample.service.impl包、子孙包下全部类的方法。blog

 四、第二个*号:表示类名,*号表示全部的类。接口

 五、*(..):最后这个星号表示方法名,*号表示全部的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。get

 

 

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()

该函数接受一个注解类的类名,当方法的运行时入参对象标注发指定的注解时,方法匹配切点。这个切点函数的匹配规则不太容易理解,咱们经过如下示意图对此进行详细讲解:

 

 

 

 

类别

函数

入参

说明

方法切点函数

execution()

方法

匹配模式串

表示知足某一匹配模式的全部目标类方法链接点。如execution(* greetTo(..))表示全部目标类中的greetTo()方法。

 

@annotation()

方法注

解类名

表示标注了特定注解的目标方法链接点。如@annotation(com.baobaotao.anno.NeedTest)表示任何标注了@NeedTest注解的目标类方法。

方法入参切点函数

args()

类名

经过判别目标类方法运行时入参对象的类型定义指定链接点。如args(com.baobaotao.Waiter)表示全部有且仅有一个按类型匹配于Waiter的入参的方法。

 

@args()

类型注

解类名

经过判别目标方法的运行时入参对象的类是否标注特定注解来指定链接点。如@args(com.baobaotao.Monitorable)表示任何这样的一个目标方法:它有一个入参且入参对象的类标注@Monitorable注解。

目标类切点函数

within()

类名匹配串

   表示特定域下的全部链接点。如within(com.baobaotao.service.*)表示com.baobaotao.service包中的全部链接点,也即包中全部类的全部方法,而within(com.baobaotao.service.*Service)表示在com.baobaotao.service包中,全部以Service结尾的类的全部链接点。

 

target()

类名

   假如目标类按类型匹配于指定类,则目标类的全部链接点匹配这个切点。如经过target(com.baobaotao.Waiter)定义的切点,Waiter、以及Waiter实现类NaiveWaiter中全部链接点都匹配该切点。

 

@within()

类型注解类名

   假如目标类按类型匹配于某个类A,且类A标注了特定注解,则目标类的全部链接点匹配这个切点。

   如@within(com.baobaotao.Monitorable)定义的切点,假如Waiter类标注了@Monitorable注解,则Waiter以及Waiter实现类NaiveWaiter类的全部链接点都匹配。

 

@target()

类型注解类名

   目标类标注了特定注解,则目标类全部链接点匹配该切点。如@target(com.baobaotao.Monitorable),假如NaiveWaiter标注了@Monitorable,则NaiveWaiter全部链接点匹配切点。

代理类切点函数

this()

类名

 代理类按类型匹配于指定类,则被代理的目标类全部链接点匹配切点。这个函数比较难理解,这里暂不举例,留待后面详解。


原文地址:http://zhuchengzzcc.iteye.com/blog/1504014

相关文章
相关标签/搜索