随笔 - 1162  文章 - 0  评论 - 16  阅读 - 59万 

一、切入点表达式作用

  切入点表达式:通过表达式的方式定位一个或多个具体的连接点。

 

二、语法细节

  1、切入点表达式的语法格式

1
execution([权限修饰符] [返回值类型] [简单类名/全类名] [方法名]([参数列表]))

  

  2、通配符

复制代码
通配符:
    *1)匹配一个或者多个字符:execution(public int com.njf.aop.calc.MyMath*r.*(int, int))
        2)匹配任意一个参数:第一个是int类型,第二个是任意类型(匹配两个参数)
            execution(public int com.njf.aop.calc.MyMath*r.*(int, *))
        3)如果 * 放在路径中,只能匹配一层路径
        4) 权限位置不能使用 * 表示,权限位置不写就行,public【可选类型】
    ..:
        1)匹配任意多个参数,任意类型参数
        2)匹配任意多层路径 execution(public int com.njf..calc.MyMath*r.*(..))

        最精确的:execution(public int com.njf.aop.calc.MyMathCalculator.add(int, int))
        最模糊的:execution(* *.*(..))
复制代码

 

    *星号:

1
2
3
4
5
6
7
1、匹配一个或者多个字符 (MyMath*r)-->开头为MyMath,结尾为r
    ("execution(public int com.achang.inter.impl.MyMath*r.*(int,int))")
2、匹配任意一个参数      *(int,*) --->任意一个方法,第一个参数为int,第二个为任意类型,有且仅有两个参数
    ("execution(public int com.achang.inter.impl.MyMathCalculator.*(int,*))")
3、只能匹配一层路径      com.achang.inter.*.MyMathCalculator --->inter路径下任意路径下的MyMathCalculator
    ("execution(public int com.achang.inter.*.MyMathCalculator.*(int,int))")
4、权限位置*不能:权限位置不写就行

   

    ..点点: 

1
2
3
4
1、匹配任意多个参数,任意类型参数   *(..) --->任意方法任意参数
    ("execution(public int com.achang.inter.impl.MyMathCalculator.*(..))")
2、匹配任意多层路径      impl..MyMath --->impl路径下的任意路径MyMath
    ("execution(public int com.achang.inter.impl..MyMath.*(int,int))")

 

    举例说明:

复制代码
execution(* com.atguigu.spring.ArithmeticCalculator.*(..))

ArithmeticCalculator接口中声明的所有方法。

第一个“*”代表任意修饰符及任意返回值。 *

第二个“”代表任意方法。 “…”匹配任意数量、任意类型的参数。

若目标类、接口与该切面类在同一个包中可以省略包名。
复制代码

 

 

  3、其他举例

    

 

    (1)

1
2
3
4
5
6
7
表达式:execution (*  com.spring.aop.ICalc.* (..))
含义
    ICalc 接口中声明的所有方法
    第一个 '*' 代表任意修饰符及任意返回值;
    第二个 '*' 代表任意方法;
    '..' 匹配任意数量、任意类型的参数;
    若目标类、接口与该切面类在同一个包中可以省略包名

 

    (2)

1
2
表达式:execution(public * ICalc.*(..) )
含义:Calc 接口的所有公有方法

 

    (3)

1
2
表达式:execution(public double ICalc*(..) )
含义:ICalc 接口中返回 double 类型数值的方法

 

    (4)

1
2
3
4
表达式:execution(public double ICalc.*(double,..))
含义:
    第一个参数为 double 类型的方法
    '..' 匹配任意数量、任意类型的参数   

 

    (5)

1
2
表达式:execution(public double ICalc.*(double,double))
含义:参数类型为 double,doule 类型的方法

 

   4、在AspectJ中,切入点表达式可以通过 “&&”、“||”、“!”等操作符结合起来。

1
2
3
4
5
表达式:execution(**.add(int,..)) || execution(**.sub(int,..))
含义:任意类中第一个参数为 int  类型的 add 方法或 sub 方法
 
表达式:!execution(* *.add(int,...))
含义:匹配不是任意类中第一个参数为 int 类型的 add 方法

 

 

三、切入点表达式应用到实际的切面类中

    

 

四、重用切入点定义

  (1)在编写 AspectJ 切面时,可以直接在通知注解中书写切入点表达式,但同一个切点表达式可能会在多个通知中重复出现;
        (2)在 AspectJ 切面中,可以通过 @PointCut 注解将一个切入点声明或简单方法。切入点的方法体通常是空的,因为将切入点定义与应用程序逻辑混在一起是不合理的;
        (3)切入点方法的访问控制符同时也控制着这个切入点的可见性。如果切入点要在多个切面中共用,最好将它们集中在一个公共的类中,在这种情况下,它们必须被声明为 public,在引入这个切入点时,必须将类名也包括在内。如果类没有与这个切面放在同一个包中,还必须包含包名。
        (4)其他通知可以通过方法名称引入该切入点;
 
    实现步骤:
1
2
3
4
5
1、随便声明一个没有实现的返回void的空方法
 
2、给方法上标注@Pointcut注解
 
3、在需要用到这个内容的注解execution属性内写入这个空方法的方法名

  

    
    案例:
      

 

     代码示例:

复制代码
    @Pointcut(value="execution(* com.spring.aop.*.*(..))")    // 重用的切入点表达式
    public void test() {}

    @Before(value="test()")                              // 使用前置通知,使用重用的切入点表达式
    public void beforeMethod(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();//获取方法的参数
        String methodName = joinPoint.getSignature().getName();//获取方法名
        System.out.println("method:"+methodName+",arguments:"+Arrays.toString(args));
    }

    @After(value="test()")                                // 使用前置通知,使用重用的切入点表达式
    public void afterMethod() {
        System.out.println("后置通知");
    }
复制代码

 

 

 

posted on   格物致知_Tony  阅读(1004)  评论(0编辑  收藏  举报
编辑推荐:
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· 面试官:你是如何进行SQL调优的?
点击右上角即可分享
微信分享提示

目录导航