一、切入点表达式作用
切入点表达式:通过表达式的方式定位一个或多个具体的连接点。
二、语法细节
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("后置通知");
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· 面试官:你是如何进行SQL调优的?