切点函数是AspectJ表达式语言的核心, 也是使用@AspectJ进行切面定义的难点.本小节我们通过具体的实例对切点函数进行深入学习.

1.@annotation()

  @annotation()表示标注了某个注解的所有方法,这个比较简单.

2.execution()

  execution()是最常使用的切点函数,其语法如下:

  execution(<修饰符模式>? <返回类型模式> <方法名模式> (<参数模式>) <异常模式>?)

  除了返回类型模式, 方法名模式, 参数模式是必须的外,其他两个都不是必须的

  (1) 通过方法签名定义切点

      • execution(public * *(..))

        匹配所有目标类的public 方法, 第一个*号代表返回类型, 第二个*号代表方法名.而..代表任意的入参

      • execution(* *To(..))

        匹配目标类所有以To结尾的方法, 第一个*代表返回类型, *To代表所有以To结尾的方法

  (2) 通过类定义切点

      • execution(* com.bao.bao.Waiter.*(..))

        匹配Waiter接口的所有方法, 第一个*号代表返回任意类型, com.bao.bao.Waiter.*代表Waiter接口中的任意方法

      • execution(* com.bao.bao.Waiter+.*(..))

        匹配Waiter接口及其所有实现类的方法, 这个和上面的区别在于,这个不但匹配Waiter接口中定义的方法, 还匹配Waiter实现类中定义的方法(但不在Waiter接口中定义),而上面的那个只匹配Waiter接口中定义的方法

  (3) 通过类包定义切点

    在类名模式串中, ".*"表示包下的所有类, 而"..*"表示包, 子孙包下的所有类

      • execution(* com.bao.bao.*(..))

        匹配com. bao.bao包下所有类的所有方法

      • execution(* com.bao.bao..*(..))

        匹配com.bao.bao包,子孙包下所有类的所有方法. ".."出现在类名中时, 后面必须跟"*"表示包,子孙包下的所有类

      • execution(* com..*.*Dao.find*(..))

        匹配包名前缀为com的任何包下类名后缀为Dao的方法, 方法名必须以find为前缀.

  (4) 通过方法入参定义切点

    切点表达式中, 方法入参部分比较复杂,可以使用"*"和".."通配符.其中"*"表示任意类型的参数;而".."表示任意类型参数且参数个数不限.

      • execution(* joke(String, *))

        匹配目标类中的joke()方法, 该方法第一个入参为String, 第二个入参可以是任意类型

      • execution(* joke(String, ..)) 

        匹配目标类中的joke()方法, 该方法第一个入参为String,后面可以有任意多个入参,且类型不限

3. args()和@args()

  args()函数的入参是类名, @args()函数的入参必须是注解类的类名.虽然args()允许在类名后面使用+通配符, 但该通配符在这里没有意义, 添加和不添加都是一样的.

  (1) args()

    该函数接收一个类名, 表示目标类的方法的入参是指定类(包括子类)时, 那么该方法匹配该切点 .如

    args(com.bao.bao.Waiter)

表示运行时入参类型是Waiter的方法, 这和execution(* *(com.bao.bao.Waiter))的区别在于后者是针对方法的签名而言, 而前者是针对方法运行时入参而言的

  (2) @args()

    该函数接受一个注解类的类名, 当方法运行时入参对象所对应的类标注了指定注解时, 该方法就匹配切点.这个切点函数的匹配规则不太容易理解...

4.within()

  within()函数定义的连接点是针对目标类而言的,而非针对运行期对象的类型而言, 这和execution()是相同的.但和execution()不同的是,execution()所指定的连接点可以大到包, 小到方法入参,而within()所指定的连接点最小范围只能是类

  (1) within(com.bao.bao.NaiveWaiter)

    匹配目标类NaiveWaiter中的所有方法, 如果切点调整为within(com.bao.bao.Waiter), 则NaiveWaiter和NaughtyWaiter中的所有方法都不匹配.

  (2) within(com.bao.bao.*)

    匹配com.bao.bao中的所有类, 但不包括子孙包

  (3) within(com.bao.bao..*)

    匹配com.bao.bao包及子孙包中的类

5.@within()和@target()

  和@annotation()及@args()函数一样, 他们也只接受注解类名作为入参,其中@target(M)匹配任意标注了@M的目标类, 而@within(M)匹配标注了@M的类及子孙类.

  @target(M)切点的匹配规则如下:

    假设NaiveWaiter标注了@Monitorable, 而其子孙类CuteNaiveWaiter没有标注@Monitorable, 则@target(com.bao.bao.Monitorable)匹配NaiveWaiter类的所有方法, 但不匹配CuteNaiveWaiter类的方法.  

  @within(M)切点的匹配规则如下: 

      假设NaiveWaiter标注了@Monitorable, 而其子孙类CuteNaiveWaiter没有标注@Monitorable, 则@within(com.bao.bao.Monitorable)匹配NaiveWaiter类的所有方法, 同时还匹配CuteNaiveWaiter类的方法.  

有一个值得注意的地方, 假如某个接口标注了@M, 则所有实现该接口的类并不匹配@within(M)

6.target()和this()

    target()切点函数通过判断目标类是否按类型匹配指定类决定连接点是否匹配,而this()则通过判断代理类是否按类型匹配指定类来决定是否和切点匹配.

  target():

    (1) target(com.bao.bao.Waiter)

      NaiveWaiter, 以及CuteNaiveWaiter的所有方法都匹配切点,包括那些未在Waiter接口中定义的方法

    

基于@AspectJ和schema的aop(三)---切点函数详解的更多相关文章

  1. (spring-第19回【AOP基础篇】)基于AspectJ和Schema的AOP

    基于AspectJ就是基于@AspectJ注解,基于Schema就是全部依靠配置文件.那么首先要了解Java注解. Java注解初探 在JDK5.0中,我们可以自定义标签,并通过Java语言的反射机制 ...

  2. 基于@AspectJ和schema的aop(一)

    在前面我们使用Pointcut和Advice描述切点和增强, 并使用Advisor整合两者描述切面.@AspectJ使用注解来描述切点和增强.两者使用的方式不同, 但是在本质上都是一样的. 我们还是用 ...

  3. 基于@AspectJ和schema的aop(二)---@AspectJ基础语法

    @AspectJ使用jdk5.0和正规的AspectJ切点表达式描述切面, 由于spring只支持方法的连接点,所以Spring只支持部分AspectJ的切点语言. 1.切点表达式函数 AspectJ ...

  4. 基于@AspectJ和schema的aop(四)---@AspectJ进阶

    @AspectJ可以使用切点函数定义切点, 我们还可以使用逻辑运算对切点进行复合运算得到复合的切点. 我们还可以对切点进行命名, 从而可以复用切点.当一个连接点匹配多个切点时, 需要考虑增强织入的顺序 ...

  5. 动态载入DLL所需要的三个函数详解(LoadLibrary,GetProcAddress,FreeLibrary)

    动态载入 DLL 动态载入方式是指在编译之前并不知道将会调用哪些 DLL 函数, 完全是在运行过程中根据需要决定应调用哪些函数. 方法是:用 LoadLibrary 函数加载动态链接库到内存,用 Ge ...

  6. 【转载】动态载入DLL所需要的三个函数详解(LoadLibrary,GetProcAddress,FreeLibrary)

    原文地址:https://www.cnblogs.com/westsoft/p/5936092.html 动态载入 DLL 动态载入方式是指在编译之前并不知道将会调用哪些 DLL 函数, 完全是在运行 ...

  7. win系统动态载入DLL所需要的三个函数详解(LoadLibrary,GetProcAddress,FreeLibrary)

    动态载入 DLL 动态载入方式是指在编译之前并不知道将会调用哪些 DLL 函数, 完全是在运行过程中根据需要决定应调用哪些函数. 方法是:用 LoadLibrary 函数加载动态链接库到内存,用 Ge ...

  8. Python第三周 函数详解

    def 函数名(): """注释说明"""" 执行逻辑体 return 返回值 定义不带参数的函数 带参数的函数 默认参数 这个是 ...

  9. Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AOP编程比较

    本篇博文用一个稍复杂点的案例来对比一下基于XML配置与基于AspectJ注解配置的AOP编程的不同. 相关引入包等Spring  AOP编程准备,请参考小编的其他博文,这里不再赘述. 案例要求: 写一 ...

随机推荐

  1. 【Origin】 叹文

    行文如流水, 千字挥手就: 偏偏伤脑筋, 哪得轻松事. -作于二零一五年五月三十日

  2. [转]Eclipse Java注释模板设置详解

    原文链接:http://blog.csdn.net/ahhsxy/archive/2009/09/11/4542682.aspx 设置注释模板的入口: Window->Preference-&g ...

  3. BroadCast Receive 生命周期

    BroadCastReceiver 简介 BroadCastReceiver 源码位于: framework/base/core/java/android.content.BroadcastRecei ...

  4. Keyframes介绍

    Keyframes被称为关键帧,其类似于Flash中的关键帧.在CSS3中其主要以“@keyframes”开头,后面紧跟着是动画名称加上一对花括号“{…}”,括号中就是一些不同时间段样式规则. @ke ...

  5. android studio ADB not responding.

    打开cmd    输入  netstat -aon|findstr "5037"   找到谁在占用5037端口 记住他的pid. 例如pid为 2028 输入  taskkill ...

  6. paper 29 :CV会议+领先研究室+专家+代码网址

    做机器视觉和图像处理方面的研究工作,最重要的两个问题:其一是要把握住国际上最前沿的内容:其二是所作工作要具备很高的实用背景.解决第一个问题的办法就是找出这个方向公认最高成就的几个超级专家(看看他们都在 ...

  7. 夺命雷公狗---DEDECMS----20dedecms取出栏目页对应的内容

    取出栏目页对应的内容 现在我们的栏目页面是可以完全正常跳转了,那么我们现在需要完成的就是让他的内容全部(电影,连续剧,综艺)分类的显示出来. 我们还是要使用{dede:arclist}标签来取出我们所 ...

  8. zw版【转发·台湾nvp系列Delphi例程】HALCON Cast 使用方式

    zw版[转发·台湾nvp系列Delphi例程]HALCON Cast 使用方式 procedure TForm1.Button1Click(Sender: TObject);var img, img1 ...

  9. 如何在图像处理工具包ImagXpress中对图像进行捕捉、复制和粘贴

    如何在在ImagXpress中进行图像的捕捉. 复制和粘贴呢?下面详细来看一下,在多种情况下,图和实现这些操作. 捕捉屏幕图像 捕捉通过ImageXView窗口绑定的屏幕范围,以及保存到一个Image ...

  10. python False

    None 空字符串 空列表 空元组 空字典 false为False