AOP切入点表达式
切入点表达式(Pointcut Expression)用于定义通知在哪些连接点执行,Spring AOP使用AspectJ切入点语法。
execution表达式
最常用的切入点表达式,匹配方法执行。
语法格式
Java
execution(修饰符? 返回类型 包名.类名.方法名(参数) 异常?)
通配符说明
| 通配符 | 含义 |
|---|---|
* | 匹配任意字符 |
.. | 匹配任意层级包或任意参数 |
+ | 匹配类及其子类 |
常用示例
Java
// 匹配所有public方法
execution(public * *(..))
// 匹配Service包下所有类的所有方法
execution(* com.example.service.*.*(..))
// 匹配Service包及子包下所有类的所有方法
execution(* com.example.service..*.*(..))
// 匹配UserService的所有方法
execution(* com.example.service.UserService.*(..))
// 匹配save开头的所有方法
execution(* save*(..))
// 匹配返回值为String的方法
execution(String com.example.service.*.*(..))
// 匹配只有一个String参数的方法
execution(* com.example.service.*.*(String))
// 匹配第一个参数为String的方法
execution(* com.example.service.*.*(String, ..))
其他切入点指示符
within - 匹配类型
匹配指定类型内的所有方法。
Java
// 匹配UserService类内的所有方法
@Pointcut("within(com.example.service.UserService)")
public void userServiceMethods() {}
// 匹配service包下所有类的所有方法
@Pointcut("within(com.example.service..*)")
public void serviceLayerMethods() {}
@annotation - 匹配注解
匹配带有指定注解的方法。
Java
// 自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
}
// 匹配带@Log注解的方法
@Pointcut("@annotation(com.example.annotation.Log)")
public void logAnnotatedMethods() {}
@within - 匹配类注解
匹配类级别注解。
Java
// 匹配带@Service注解的类
@Pointcut("@within(org.springframework.stereotype.Service)")
public void serviceClassMethods() {}
bean - 匹配Bean名称
Spring特有,按Bean名称匹配。
Java
// 匹配名为userService的Bean
@Pointcut("bean(userService)")
public void userServiceBean() {}
// 匹配以Service结尾的Bean
@Pointcut("bean(*Service)")
public void allServiceBeans() {}
args - 匹配参数类型
Java
// 匹配第一个参数为String的方法
@Pointcut("args(String, ..)")
public void firstArgString() {}
组合表达式
使用逻辑运算符组合多个切入点。
Java
// 与(&&)
@Pointcut("execution(* com.example.service.*.*(..)) && args(String)")
public void serviceWithStringArg() {}
// 或(||)
@Pointcut("execution(* com.example.service.*.*(..)) || execution(* com.example.dao.*.*(..))")
public void serviceOrDao() {}
// 非(!)
@Pointcut("execution(* com.example.service.*.*(..)) && !execution(* com.example.service.UserService.*(..))")
public void serviceExceptUserService() {}
切入点复用
使用@Pointcut定义可复用的切入点。
text
@Aspect
@Component
public class LoggingAspect {
// 定义可复用的切入点
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceLayer() {}
// 引用切入点
@Before("serviceLayer()")
public void logBefore(JoinPoint joinPoint) {
System.out.println("执行: " + joinPoint.getSignature().getName());
}
// 在其他切面引用
@After("serviceLayer()")
public void logAfter(JoinPoint joinPoint) {
System.out.println("完成: " + joinPoint.getSignature().getName());
}
}
要点总结
- execution是最常用的切入点表达式
*匹配任意字符,..匹配任意层级或参数- within匹配类型,@annotation匹配方法注解
- bean是Spring特有,按Bean名称匹配
- 可使用&&、||、!组合多个切入点表达式
📝 发现内容有误?点击此处直接编辑