(III)AOP:第四节:切入点表达式

一、切入点表达式作用

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

二、语法细节

  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、匹配一个或者多个字符 (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、匹配任意多个参数,任意类型参数   *(..) --->任意方法任意参数
    ("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)

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

    (2)

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

    (3)

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

    (4)

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

    (5)

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

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

表达式:execution(**.add(int,..)) || execution(**.sub(int,..))
含义:任意类中第一个参数为 int  类型的 add 方法或 sub 方法

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

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

    

四、重用切入点定义

  (1)在编写 AspectJ 切面时,可以直接在通知注解中书写切入点表达式,但同一个切点表达式可能会在多个通知中重复出现;
        (2)在 AspectJ 切面中,可以通过 @PointCut 注解将一个切入点声明或简单方法。切入点的方法体通常是空的,因为将切入点定义与应用程序逻辑混在一起是不合理的;
        (3)切入点方法的访问控制符同时也控制着这个切入点的可见性。如果切入点要在多个切面中共用,最好将它们集中在一个公共的类中,在这种情况下,它们必须被声明为 public,在引入这个切入点时,必须将类名也包括在内。如果类没有与这个切面放在同一个包中,还必须包含包名。
        (4)其他通知可以通过方法名称引入该切入点;
 
    实现步骤:
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("后置通知");
    }
 
原文地址:https://www.cnblogs.com/niujifei/p/15448842.html