
在Spring AOP中,切入点表达式(Pointcut Expression)用于精确匹配需要被拦截的连接点(通常是方法)。Spring AOP采用AspectJ的切入点表达式语言,配置方式灵活且功能强大。以下是切入点表达式的核心配置方法和常用示例:
切入点表达式的核心语法基于execution关键字,基本格式如下:
execution(
[修饰符] 返回值类型
[包名.类名.]方法名(参数列表)
[throws 异常类型]
)public、private等,省略时匹配任意修饰符。*表示任意返回值。*和..可用于通配(..表示当前包及子包)。*表示任意方法名。()表示无参,(..)表示任意参数,(*)表示单个任意参数。通配符 | 作用 | 示例 |
|---|---|---|
| 匹配单个任意字符(类名、方法名、参数类型等) |
|
| 匹配多个任意字符,在包路径中表示“当前包及所有子包”,在参数中表示“任意参数(包括无参)” |
|
| 匹配指定类及其所有子类 |
|
以下是实际开发中常用的切入点表达式配置:
// 匹配com.example.service包下所有类的所有方法(不包含子包)
@Pointcut("execution(* com.example.service.*.*(..))")
public void servicePointcut() {}
// 匹配com.example.service包及所有子包下的所有方法
@Pointcut("execution(* com.example.service..*.*(..))")
public void serviceWithSubPackagePointcut() {}// 匹配UserService类的所有方法
@Pointcut("execution(* com.example.service.UserService.*(..))")
public void userServicePointcut() {}
// 匹配UserService及其子类的所有方法
@Pointcut("execution(* com.example.service.UserService+.*(..))")
public void userServiceAndSubClassPointcut() {}// 匹配所有以"get"开头的方法
@Pointcut("execution(* com.example.service.*.get*(..))")
public void getMethodPointcut() {}
// 匹配所有以"save"或"update"开头的方法
@Pointcut("execution(* com.example.service.*.save*(..)) || execution(* com.example.service.*.update*(..))")
public void saveOrUpdatePointcut() {}// 匹配无参数的方法
@Pointcut("execution(* com.example.service.*.*())")
public void noArgMethodPointcut() {}
// 匹配第一个参数为Long类型的方法
@Pointcut("execution(* com.example.service.*.*(Long, ..))")
public void firstArgIsLongPointcut() {}
// 匹配参数数量为2且类型任意的方法
@Pointcut("execution(* com.example.service.*.*(*, *))")
public void twoArgMethodPointcut() {}// 匹配返回值为String类型的方法
@Pointcut("execution(String com.example.service.*.*(..))")
public void returnStringPointcut() {}
// 匹配返回值为void的方法
@Pointcut("execution(void com.example.service.*.*(..))")
public void returnVoidPointcut() {}除了execution,还可以通过@annotation(方法注解)或@within(类注解)匹配:
// 匹配标注了@Loggable注解的方法
@Pointcut("@annotation(com.example.annotation.Loggable)")
public void loggableMethodPointcut() {}
// 匹配标注了@Service注解的类中的所有方法
@Pointcut("@within(org.springframework.stereotype.Service)")
public void serviceClassPointcut() {}使用逻辑运算符(&&、||、!)组合多个切入点:
// 匹配service包中且以"get"开头的方法
@Pointcut("execution(* com.example.service..*.*(..)) && execution(* *..get*(..))")
public void serviceGetMethodPointcut() {}
// 匹配service包中除了UserService的其他类的方法
@Pointcut("execution(* com.example.service..*.*(..)) && !execution(* com.example.service.UserService.*(..))")
public void excludeUserServicePointcut() {}在Spring AOP中,切入点表达式通常通过@Pointcut注解定义,然后在通知(Advice)中引用:
@Aspect
@Component
public class LogAspect {
// 定义切入点
@Pointcut("execution(* com.example.service..*.*(..))")
public void servicePointcut() {}
// 在切入点上应用前置通知
@Before("servicePointcut()")
public void beforeServiceMethod(JoinPoint joinPoint) {
// 通知逻辑(如日志记录)
}
}也可以直接在通知注解中编写表达式(适合简单场景):
@Before("execution(* com.example.service.UserService.getUserById(..))")
public void beforeGetUser(JoinPoint joinPoint) {
// 逻辑
}execution(* *(..))会匹配所有方法,影响性能)。通过灵活配置切入点表达式,可以精确控制AOP对哪些方法生效,从而高效地实现日志、事务、安全等横切功能。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。