切入点表达式

/*
*作者:呆萌老师
*☑csdn认证讲师
*☑51cto高级讲师
*☑腾讯课堂认证讲师
*☑网易云课堂认证讲师
*☑华为开发者学堂认证讲师
*☑爱奇艺千人名师计划成员
*在这里给大家分享技术、知识和生活
*各种干货,记得关注哦!
*vx:it_daimeng
*/

切入点表达式:

1、切入点表达式:对指定的方法进行拦截,并且生成代理表达式。
表达式语法:

execution([修饰符] 返回值类型 包名.类名.方法名(参数))

execution( public void com.test.service.impl.UsersService.add() )

2、表达式不同写法
1.匹配指定方法

<aop:pointcut expression="execution( public void com.test.service.impl.UsersService.add())" id="pt"/>`

2.默认 public 可以省略

<aop:pointcut expression="execution( void com.test.service.impl.UsersService.add())" id="pt"/>

3.匹配任何返回值

<aop:pointcut expression="execution( * com.test.service.impl.UsersService.add())" id="pt"/>`

4.参数列表可以使用 * , 表示可以是任何的数据类型,但必须有参数

<aop:pointcut expression="execution( * com.test.service.impl.UsersService.add(*))" id="pt"/>`

5.参数列表可以使用 … 表示有无参数均可,有参数可以是任意类型

<aop:pointcut expression="execution( *com.test.service.impl.UsersService.add(..))" id="pt"/>`

6.使用…来表示当前包,及其子包

<aop:pointcut expression="execution( * com..UsersService.add(..))" id="pt"/>`

7.类名可以使用*号,表示任意类

<aop:pointcut expression="execution( * com..*.add(..))" id="pt"/>`

8.类名也可以使用 * 加后缀,表示这个后缀的所有类

<aop:pointcut expression="execution( * com..*Service.add(..))" id="pt"/>

9.方法名可以使用*号,表示任意方法

<aop:pointcut expression="execution( * com..*.*(..))" id="pt"/>`

10.全通配方式execution( * …* ( … ) )

<aop:pointcut expression="execution(public * *(..))" id="pt"/>

11.拦截所有save开头的方法

<aop:pointcut expression="execution(* save*(..))" id="pt"/>

12.多个表达式

| <aop:pointcut expression="execution(* 包名.类名.方法名()) || execution(* 包名.类名(不同的类).方法名())" id="pt"/> <aop:pointcut expression="execution(* 包名.类名.方法名()) or execution(* 包名.类名(不同的类).方法名())" id="pt"/> 

13.取非值

<aop:pointcut expression="!execution(* 包名.类名.方法名())" id="pt"/> 
<aop:pointcut expression=" not execution(* 包名.类名.方法名())" id="pt"/>
### 关于AOP切入点表达式的语法与示例 #### 切入点表达式概述 Spring AOP 中的切入点表达式是一种强大的工具,用于精确定义程序中的哪些连接点(Join Point)需要执行通知逻辑。这些表达式基于 AspectJ 的语法构建,能够灵活地匹配特定的方法签名或其他条件。 #### 支持的切入点指示符 Spring AOP 提供了多种切入点指示符来满足不同的需求。常见的有 `execution`、`within` 和 `args` 等[^2]。其中最常用的是 `execution` 表达式,它可以用来匹配方法的执行。 --- #### 示例:使用 `execution` 定义切入点 下面是一个典型的切入点表达式示例: ```java @Before("execution(* com.example.service.*.*(..))") public void beforeAdvice(JoinPoint joinPoint) { System.out.println("Method " + joinPoint.getSignature().getName() + " is executing."); } ``` 此表达式的作用是拦截 `com.example.service` 包下所有类的所有方法调用,并在其之前打印一条日志消息。具体解释如下: - `*`: 返回任意类型的值。 - `com.example.service.*`: 指定包下的任何类。 - `*(..)`: 方法名可以是任意字符,参数列表也可以为空或包含任意数量的参数。 --- #### 使用通配符扩展表达式 可以通过通配符进一步细化切入点的定义。例如: ```java @AfterReturning(pointcut = "execution(void com.Demo.service.impl.DeptServiceImpl.delete(java.lang.Integer))", returning = "result") public void afterDeleteAdvice(Object result) { System.out.println("The delete method has been executed and returned: " + result); } ``` 在此示例中,切入点仅限于 `DeptServiceImpl` 类中的 `delete(Integer)` 方法[^3]。 --- #### 配置异常通知 如果希望在某个方法抛出异常时触发通知,则可以使用 `<aop:after-throwing>` 或者相应的注解形式。例如: ```java @AfterThrowing(pointcut = "execution(* com.example.service.UserService.addUser(User))", throwing = "ex") public void logException(Exception ex) { System.err.println("An exception occurred while adding user: " + ex.getMessage()); } ``` 这里的 `pointcut` 参数指定了切入点表达式,而 `throwing` 参数则绑定了具体的异常对象[^4]。 --- #### 更复杂的表达式组合 除了单一的 `execution` 外,还可以结合其他关键词创建更精细的过滤器。比如限定某些包内的操作或者根据传参类型筛选目标函数: ```java @Around("@annotation(com.example.annotations.LogExecutionTime)") public Object aroundLogExecutionTime(ProceedingJoinPoint pjp) throws Throwable { long startTime = System.currentTimeMillis(); try { return pjp.proceed(); // 执行被代理的方法 } finally { long elapsedTime = System.currentTimeMillis() - startTime; System.out.println(pjp.getSignature() + " took " + elapsedTime + " ms"); } } ``` 这里展示了如何通过自定义注解作为切入点的一部分[^2]。 --- #### 解析实际案例 考虑这样一个场景——监控服务层所有公开 API 的性能表现: ```java @Aspect @Component public class PerformanceMonitor { @Around("execution(public * com.myapp.service..*(..)) && args(user, ..)") public Object monitorServiceMethods(ProceedingJoinPoint jp, User user) throws Throwable { String methodName = jp.getSignature().toShortString(); StopWatch watch = new StopWatch(methodName); try { watch.start(); return jp.proceed(); } finally { watch.stop(); logger.info("{} completed in {}ms with argument {}", methodName, watch.getTotalTimeMillis(), user.getName()); } } } ``` 上述代码片段说明了一个复杂的应用实例,即只针对带有特定参数的服务端口进行耗时统计[^5]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值