news 2026/4/22 13:43:59

Spring AOP表达式速查手册

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring AOP表达式速查手册

📍切入点表达式常见形式速查手册


🎯execution(最常用)

语法模板

execution(修饰符?返回类型 包名.类名.方法名(参数)异常?)

可以使用通配符描述切入点

  • “ * ” :单个独立的任意符号,可以通配任意返回值、包名、类名、方法名、任意类型的一个参数,也可以通配包、类、方法名的一部分
  • … :多个连续的任意符号,可以通配任意层级的包,或任意类型、任意个数的参数

常用形式

1. 按包匹配
// 精确包匹配execution(*com.example.service.*.*(..))// service包下所有类的方法execution(*com.example.service..*.*(..))// service包及其子包下所有方法// 多级包匹配execution(*com..service.*.*(..))// 任意父包下的service包
2. 按类匹配
// 精确类匹配execution(*com.example.service.UserService.*(..))// UserService所有方法// 按类名模式匹配execution(*com.example.service.*Service.*(..))// 以Service结尾的类execution(*com.example.service.*Impl.*(..))// 以Impl结尾的类
3. 按方法名匹配
// 精确方法名execution(*com.example.service.UserService.save(..))// 特定方法// 模式匹配方法名execution(*com.example.service.*.save*(..))// 以save开头的方法execution(*com.example.service.*.*User(..))// 以User结尾的方法execution(*com.example.service.*.get*())// 无参的getter方法execution(*com.example.service.*.set*(*))// 单个参数的setter方法
4. 按参数匹配
// 精确参数execution(*com.example.service.*.*(String,int))// 参数为(String, int)// 参数模式execution(*com.example.service.*.*(*))// 单个任意参数execution(*com.example.service.*.*(*,*))// 两个任意参数execution(*com.example.service.*.*(*,String))// 第二个参数为Stringexecution(*com.example.service.*.*(..,String))// 最后一个参数为Stringexecution(*com.example.service.*.*(java.lang.String))// 明确指定类型execution(*com.example.service.*.*(com.example.User))// 自定义类型参数
5. 按返回类型匹配
execution(voidcom.example.service.*.*(..))// 返回void的方法execution(Stringcom.example.service.*.*(..))// 返回String的方法execution(List<*>com.example.service.*.*(..))// 返回List的方法execution(*com.example.service.*.*(..))// 任意返回值

🏷️@annotation(基于注解)

形式

// 匹配方法上的注解@annotation(org.springframework.transaction.annotation.Transactional)@annotation(com.example.annotation.Log)@annotation(com.example.annotation.Cacheable)// 组合使用@annotation(com.example.annotation.Log)&&execution(*com.example.service.*.*(..))

示例注解

// 自定义注解@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public@interfaceLog{Stringvalue()default"";}// 使用@Log("用户操作")publicvoidsaveUser(){...}

📦within(按类型)

形式

// 精确类within(com.example.service.UserService)// UserService所有方法// 包级别within(com.example.service.*)// service包下所有类within(com.example.service..*)// service包及其子包下所有类// 接口/实现类within(com.example.service.BaseService+)// BaseService及其实现类

🏢@within(按类上的注解)

形式

// 匹配类上有特定注解的所有方法@within(org.springframework.stereotype.Service)// 所有@Service类@within(org.springframework.web.bind.annotation.RestController)// 所有@RestController类@within(com.example.annotation.Secured)// 所有@Secured注解类

🧾bean(Spring特有)

形式

// 按Bean名称bean(userService)// 名为userService的Beanbean(*Service)// 以Service结尾的Beanbean(user*)// 以user开头的Beanbean(*Controller)// 以Controller结尾的Beanbean(*ServiceImpl)// 以ServiceImpl结尾的Bean

🔗args(按参数类型/注解)

形式

// 按参数类型args(java.lang.String)// 第一个参数是Stringargs(java.lang.String,java.lang.Long)// 第一个String,第二个Longargs(com.example.User,..)// 第一个参数是User,后面任意// 按参数注解@args(javax.validation.Valid)// 参数有@Valid注解@args(com.example.annotation.NotEmpty)// 参数有@NotEmpty注解

🔄this/target(按代理/目标类型)

形式

// JDK代理this(com.example.service.UserService)// 代理对象是UserService类型target(com.example.service.UserService)// 目标对象是UserService类型// CGLIB代理(两者相同)this(com.example.service.UserServiceImpl)target(com.example.service.UserServiceImpl)

组合表达式

逻辑运算符

// AND (&&)execution(*com.example.service.*.*(..))&&within(com.example.service.*)execution(*com.example.service.*.*(..))&&@annotation(org.springframework.transaction.annotation.Transactional)// OR (||)execution(*com.example.service.*.save*(..))||execution(*com.example.service.*.update*(..))@annotation(com.example.annotation.Log)||@annotation(com.example.annotation.Monitor)// NOT (!)execution(*com.example.service.*.*(..))&&!execution(*com.example.service.*.get*(..))within(com.example.controller.*)&&!@annotation(com.example.annotation.SkipAuth)

实际组合示例

// 1. 监控Service层非查询方法@Pointcut("within(@org.springframework.stereotype.Service *) && "+"execution(* *.*(..)) && "+"!execution(* *.get*(..)) && "+"!execution(* *.find*(..)) && "+"!execution(* *.select*(..))")publicvoidserviceWriteOperation(){}// 2. 权限控制:Controller层需要鉴权的方法@Pointcut("within(@org.springframework.web.bind.annotation.RestController *) && "+"(@annotation(org.springframework.web.bind.annotation.PostMapping) || "+" @annotation(org.springframework.web.bind.annotation.PutMapping) || "+" @annotation(org.springframework.web.bind.annotation.DeleteMapping))")publicvoidneedAuthOperation(){}// 3. 数据库操作监控@Pointcut("execution(* com.example.repository.*.*(..)) || "+"execution(* com.example.dao.*.*(..))")publicvoiddatabaseOperation(){}// 4. 排除特定方法@Pointcut("within(com.example.service.*) && "+"!execution(* com.example.service.HealthCheckService.*(..))")publicvoidserviceExcludeHealthCheck(){}

📝命名切入点(可复用)

定义

@Aspect@ComponentpublicclassSystemArchitecture{// 1. 分层架构@Pointcut("within(@org.springframework.stereotype.Service *)")publicvoidserviceLayer(){}@Pointcut("within(@org.springframework.web.bind.annotation.RestController *)")publicvoidcontrollerLayer(){}@Pointcut("within(@org.springframework.stereotype.Repository *)")publicvoidrepositoryLayer(){}// 2. 注解定义@Pointcut("@annotation(com.example.annotation.Log)")publicvoidloggable(){}@Pointcut("@annotation(com.example.annotation.Cacheable)")publicvoidcacheable(){}@Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)")publicvoidtransactional(){}// 3. 组合定义@Pointcut("serviceLayer() && loggable()")publicvoidloggableService(){}@Pointcut("controllerLayer() && transactional()")publicvoidtransactionalController(){}}// 在其他切面中使用@Before("SystemArchitecture.serviceLayer()")publicvoidbeforeService(){...}

📊实际开发常用形式总结

场景推荐形式示例
全局日志within + 注解within(@org.springframework.stereotype.Service *)
事务管理@annotation@annotation(org.springframework.transaction.annotation.Transactional)
权限控制@annotation + execution@annotation(com.example.annotation.RequireAuth)
缓存切面@annotation@annotation(com.example.annotation.Cacheable)
性能监控execution + 排除execution(* com.example.service.*.*(..)) && !execution(* *.get*(..))
参数校验argsargs(com.example.dto.*)
异常处理within + 包名within(com.example.controller..*)
特定Beanbeanbean(userService)

🎯按优先级排序

// 执行顺序:从精确到宽泛1.@annotation(com.example.CustomAnnotation)// 最精确2.execution(*com.example.service.UserService.save(..))3.execution(*com.example.service.UserService.*(..))4.within(com.example.service.UserService)5.execution(*com.example.service.*.*(..))6.within(com.example.service.*)// 最宽泛7.execution(**.*(..))

⚠️常见错误

错误示例

// ❌ 过于宽泛(影响性能)execution(**.*(..))// ❌ 缺少参数括号execution(*com.example.service.*.*)// ❌ 包路径错误execution(*com.example.*Service.*(..))// 包名中包含通配符// ✅ 正确做法execution(*com.example.service.*Service.*(..))// 类名中包含通配符

最佳实践

// 1. 优先使用注解方式@annotation(com.example.annotation.Log)// 2. 精确匹配,避免扫描过多类within(com.example.service..*)// 3. 组合使用,提高可读性@Pointcut("within(com.example.service..*) && "+"@annotation(org.springframework.transaction.annotation.Transactional)")publicvoidtransactionalService(){}

🔧调试技巧

1. 查看匹配的方法

@Aspect@ComponentpublicclassDebugAspect{@Before("yourPointcut()")publicvoiddebug(JoinPointjoinPoint){System.out.println("匹配方法: "+joinPoint.getSignature().toShortString());}}

2. 测试切入点表达式

// 使用AspectJ工具测试// 下载aspectjweaver,使用ajc编译测试

📚速查表

✅ execution - 按方法签名匹配(最灵活) ✅ @annotation - 按方法注解匹配(最常用) ✅ within - 按类型/包匹配 ✅ @within - 按类注解匹配 ✅ bean - 按Spring Bean名称匹配 ✅ args - 按参数类型/注解匹配 ✅ this/target - 按代理/目标类型匹配 ✅ 组合 - 使用&&、||、!组合多个条件

💎一句话总结

切入点表达式选择指南:

要精确 → 用@annotation 要批量 → 用within 要灵活 → 用execution 要简单 → 用bean 要组合 → 用逻辑运算符

记住:切入点越精确,性能越好,维护越容易!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 5:40:24

3分钟掌握es-client:Elasticsearch可视化工具的5大核心功能

3分钟掌握es-client&#xff1a;Elasticsearch可视化工具的5大核心功能 【免费下载链接】es-client elasticsearch客户端&#xff0c;issue请前往码云&#xff1a;https://gitee.com/qiaoshengda/es-client 项目地址: https://gitcode.com/gh_mirrors/es/es-client 你是…

作者头像 李华
网站建设 2026/4/18 12:59:52

企业数据API对接厂商选型指南:技术架构、评估标准与最佳实践

在数字化转型浪潮中&#xff0c;企业数据已成为核心资产。如何高效、安全地将分散在不同系统&#xff08;如CRM、ERP、SCM、财务软件、物联网设备等&#xff09;的数据进行整合与流动&#xff0c;成为企业提升运营效率、驱动业务创新的关键。然而&#xff0c;数据API对接过程面…

作者头像 李华
网站建设 2026/4/22 18:39:18

B站字幕一键获取:从复杂到简单的终极解决方案

B站字幕一键获取&#xff1a;从复杂到简单的终极解决方案 【免费下载链接】BiliBiliCCSubtitle 一个用于下载B站(哔哩哔哩)CC字幕及转换的工具; 项目地址: https://gitcode.com/gh_mirrors/bi/BiliBiliCCSubtitle 你是否曾经遇到过这样的情况&#xff1a;在B站看到一个精…

作者头像 李华
网站建设 2026/4/17 8:53:29

120亿参数改写效率标杆:GLM-4.5-Air重塑智能代理格局

120亿参数改写效率标杆&#xff1a;GLM-4.5-Air重塑智能代理格局 【免费下载链接】GLM-4.5-Air 项目地址: https://ai.gitcode.com/hf_mirrors/unsloth/GLM-4.5-Air 导语 当企业还在为大模型部署成本居高不下而发愁时&#xff0c;智谱AI推出的GLM-4.5-Air以1060亿总参…

作者头像 李华