news 2026/6/23 17:47:24

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/6/23 17:45:51

QuickAdd API实战指南:打造你的专属智能笔记工作流

QuickAdd API实战指南&#xff1a;打造你的专属智能笔记工作流 【免费下载链接】quickadd QuickAdd for Obsidian 项目地址: https://gitcode.com/gh_mirrors/qu/quickadd 你是否曾经为重复的笔记创建流程而烦恼&#xff1f;每天要手动填写相同的模板、复制相似的内容、…

作者头像 李华
网站建设 2026/6/23 15:27:53

Windows系统文件samlib.dll缺失损坏问题 下载修复

在使用电脑系统时经常会出现丢失找不到某些文件的情况&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编写的&#xff0c;所以这类软件的运行需要依赖微软Visual C运行库&#xff0c;比如像 QQ、迅雷、Adobe 软件等等&#xff0c;如果没有安装VC运行库或者安装…

作者头像 李华
网站建设 2026/6/16 14:45:32

鸣潮自动化工具完整使用教程:从零开始轻松掌握智能辅助

鸣潮自动化工具完整使用教程&#xff1a;从零开始轻松掌握智能辅助 【免费下载链接】ok-wuthering-waves 鸣潮 后台自动战斗 自动刷声骸上锁合成 自动肉鸽 Automation for Wuthering Waves 项目地址: https://gitcode.com/GitHub_Trending/ok/ok-wuthering-waves 还在为…

作者头像 李华
网站建设 2026/6/22 16:32:20

MethylDackel:BS-seq甲基化提取的终极利器

MethylDackel&#xff1a;BS-seq甲基化提取的终极利器 【免费下载链接】MethylDackel A (mostly) universal methylation extractor for BS-seq experiments. 项目地址: https://gitcode.com/gh_mirrors/me/MethylDackel MethylDackel是一款专为BS-seq&#xff08;亚硫酸…

作者头像 李华
网站建设 2026/6/17 7:49:38

RookieAI_yolov8:2025年游戏AI自瞄技术完全指南

RookieAI_yolov8&#xff1a;2025年游戏AI自瞄技术完全指南 【免费下载链接】RookieAI_yolov8 基于yolov8实现的AI自瞄项目 项目地址: https://gitcode.com/gh_mirrors/ro/RookieAI_yolov8 RookieAI_yolov8作为基于YOLOv8深度优化的开源AI自瞄项目&#xff0c;通过先进的…

作者头像 李华
网站建设 2026/6/17 16:57:10

pywebview与React集成的终极指南:高效构建跨平台桌面应用

pywebview与React集成的终极指南&#xff1a;高效构建跨平台桌面应用 【免费下载链接】pywebview Build GUI for your Python program with JavaScript, HTML, and CSS 项目地址: https://gitcode.com/gh_mirrors/py/pywebview 你是否厌倦了传统桌面应用开发的复杂性&am…

作者头像 李华