AOP 切入点表达式

一、先明确核心概念

  • @Pointcut:定义切入点,即指定 AOP 通知(如 @Before)要作用于哪些方法;
  • execution():最常用的切入点表达式语法,格式为:execution(修饰符? 返回值 包名.类名.方法名(参数类型) throws异常?)其中?表示可选,核心是返回值、包类路径、方法名、参数这四部分。
  • @Before("pt()"):表示在pt()切入点匹配的方法执行之前,执行before()方法中的逻辑(打印日志)。

二、逐行拆解注释 / 未注释的切入点表达式

1. 精准匹配(指定全路径 + 方法 + 参数)
//@Pointcut("execution(public void com.itheima.service.impl.DeptServiceImpl.delete(java.lang.Integer))")
  • 含义:匹配com.itheima.service.impl.DeptServiceImpl类中,public修饰、返回值为void、方法名delete、参数为Integer类型的方法;
  • 特点:最精准,修饰符(public)、全类名、方法名、参数都明确指定,仅匹配这一个方法。
//@Pointcut("execution(void com.itheima.service.impl.DeptServiceImpl.delete(java.lang.Integer))")
  • 含义:去掉了public修饰符,匹配该类中任意修饰符(public/private/protected)的delete(Integer)方法;
  • 特点:修饰符可选,省略后匹配所有修饰符的同名方法。
//@Pointcut("execution(void delete(java.lang.Integer))") //包名.类名不建议省略
  • 含义:省略了包名和类名,理论上匹配所有类中返回值void、方法名delete、参数Integer的方法;
  • 问题:范围太广,容易匹配到非目标方法,因此注释中提示 “包名。类名不建议省略”。
//@Pointcut("execution(void com.itheima.service.DeptService.delete(java.lang.Integer))")
  • 含义:匹配接口DeptService中的delete(Integer)方法;
  • 关键:Spring AOP 中,即使切入点写的是接口方法,也会匹配接口的实现类(如 DeptServiceImpl)的对应方法,这是 AOP 面向接口编程的特性。
2. 通配符匹配(*、..)
//@Pointcut("execution(void com.itheima.service.DeptService.*(java.lang.Integer))")
  • 含义:匹配DeptService接口中所有方法名、返回值void、参数为Integer的方法;
  • 通配符*:表示 “任意”,此处替代方法名,即DeptService中所有返回void且参数是Integer的方法都会被匹配。
//@Pointcut("execution(* com.*.service.DeptService.*(*))")
  • 拆解
    • 第一个*:返回值任意(void/int/Object 等);
    • com.*.service:匹配com任意一级子包service包(如com.abc.servicecom.def.service,但不匹配com.abc.def.service);
    • 第二个*:方法名任意;
    • (*):参数为任意一个参数(类型不限);
  • 含义:匹配com.xxx.service.DeptService中所有 “单个参数” 的方法(返回值任意)。
//@Pointcut("execution(* com.itheima.service.*Service.delete*(*))")
  • 拆解
    • *Service:匹配service包下所有以 Service 结尾的类 / 接口(如 DeptService、EmpService);
    • delete*:匹配方法名以delete开头的方法(如 delete、deleteById、deleteBatch);
    • (*):单个任意类型参数;
  • 含义:匹配com.itheima.service包下所有 Service 接口 / 类中,以delete开头、带单个参数的方法(返回值任意)。
//@Pointcut("execution(* com.itheima.service.DeptService.*(..))")
  • 拆解
    • *(..)*是方法名任意,..表示 “任意个数、任意类型的参数”(0 个、1 个、多个都匹配);
  • 含义:匹配DeptService所有方法(无论返回值、无论参数),这是匹配某个接口 / 类所有方法的常用写法。
//@Pointcut("execution(* com..DeptService.*(..))")
  • 拆解com..DeptService..表示 “com 包下任意层级的子包”(如com.service.DeptServicecom.itheima.service.DeptServicecom.itheima.abc.service.DeptService);
  • 含义:匹配 com 包下任意层级中DeptService类 / 接口的所有方法。
//@Pointcut("execution(* com..*.*(..))")
  • 含义:匹配com包下所有类、所有方法(返回值任意、参数任意);
  • 特点:范围极广,几乎匹配项目中所有 com 包下的方法,一般仅用于测试。
//@Pointcut("execution(* *(..))") //慎用
  • 含义:匹配整个项目中所有方法(无任何包、类、方法限制);
  • 提示慎用:会导致 AOP 通知作用于所有方法,包括 Spring 内置方法(如 Controller、Service、甚至框架自身的方法),性能极差且易出问题。
3. 最终生效的组合表达式(重点)
@Pointcut("execution(* com.itheima.service.DeptService.list()) || " + "execution(* com.itheima.service.DeptService.delete(java.lang.Integer))") private void pt(){}
  • 核心语法||:逻辑 “或”,表示匹配任意一个表达式的方法;
  • 拆解
    1. execution(* com.itheima.service.DeptService.list())
      • 匹配DeptService接口中无参数、方法名 list的方法(*表示返回值任意);
    2. execution(* com.itheima.service.DeptService.delete(java.lang.Integer))
      • 匹配DeptService接口中方法名 delete、参数为 Integer的方法(返回值任意);
  • 最终效果@Before通知会在DeptService.list()DeptService.delete(Integer)这两个方法执行前触发,打印日志MyAspect6 ... before ...

三、核心语法规则总结

语法符号含义示例
*通配符,匹配 “任意一个”*(返回值任意)、delete*(方法名以 delete 开头)
..通配符,匹配 “任意层级 / 任意个数”com..Service(com 下任意层级的 Service 类)、(..)(任意参数)
``逻辑或,匹配任意一个表达式表达式 A表达式 B
&&逻辑与,匹配同时满足的表达式表达式 A && 表达式 B
!逻辑非,匹配不满足的表达式! 表达式 A

四、实战注意事项

  1. 精准匹配优先:生产环境尽量使用全路径 + 方法名 + 参数的精准表达式,避免通配符范围过大;
  2. 面向接口编程:切入点写接口方法(如 DeptService),会自动匹配实现类(DeptServiceImpl)的方法,符合 Spring 规范;
  3. 组合表达式:通过||/&&/!可以灵活组合多个切入点,满足复杂匹配需求;
  4. 访问修饰符:execution 表达式中修饰符(public/private)可选,省略时匹配所有修饰符。

总结

  1. 这段代码的核心是通过@Pointcut定义切入点,最终仅匹配DeptService.list()DeptService.delete(Integer)两个方法;
  2. execution()表达式的核心是 “返回值 + 包类路径 + 方法名 + 参数”,配合*/..通配符和||逻辑符可灵活匹配;
  3. 通配符使用需谨慎,范围过大(如execution(* *(..)))会导致性能问题,生产环境优先精准匹配;
  4. @Before("pt()")表示在匹配的方法执行前,执行before()方法的日志打印逻辑。

Spring AOP 中 @annotation 切入点表达式详解

@annotation是 Spring AOP 中另一种核心的切入点表达式语法,它的核心逻辑是:匹配所有标注了指定注解的方法,相比execution()(按方法路径 / 参数匹配),@annotation更灵活、更贴合 “面向业务场景” 的切入点定义(比如标记 “需要日志”“需要权限校验” 的方法)。

一、@annotation 基本语法

1. 核心格式
@Pointcut("@annotation(注解的全限定类名)") // 简写(若注解和切面类在同一包,可省略包名) @Pointcut("@annotation(自定义注解类名)")
2. 核心逻辑

只要目标方法上标注了指定的注解,该方法就会被切入点匹配,AOP 通知(@Before/@After 等)就会作用于该方法。

二、完整示例(从自定义注解到切面实现)

我们通过 “给方法加日志注解,切面拦截所有带该注解的方法” 这个场景,完整演示@annotation的用法:

步骤 1:定义自定义注解(标记需要拦截的方法)
// 自定义注解:标记需要打印日志的方法 @Target(ElementType.METHOD) // 注解仅作用于方法 @Retention(RetentionPolicy.RUNTIME) // 运行时生效(AOP需要运行时识别) public @interface LogAnnotation { // 可自定义属性,比如日志描述 String value() default ""; }
步骤 2:在目标方法上添加该注解
@Service public class DeptServiceImpl implements DeptService { // 给list方法添加自定义日志注解 @LogAnnotation("查询所有部门") @Override public List<Dept> list() { // 业务逻辑 return new ArrayList<>(); } // 给delete方法添加自定义日志注解 @LogAnnotation("删除部门") @Override public void delete(Integer id) { // 业务逻辑 } // 该方法无注解,不会被切面拦截 @Override public void save(Dept dept) { // 业务逻辑 } }
步骤 3:编写切面,用 @annotation 匹配注解方法
@Component @Aspect @Slf4j public class LogAspect { // 核心:匹配所有标注了LogAnnotation注解的方法 @Pointcut("@annotation(com.itheima.anno.LogAnnotation)") private void logPt(){} // 前置通知:拦截所有带@LogAnnotation的方法 @Before("logPt()") public void beforeLog(JoinPoint joinPoint) { // 获取注解属性(可选) MethodSignature signature = (MethodSignature) joinPoint.getSignature(); LogAnnotation annotation = signature.getMethod().getAnnotation(LogAnnotation.class); log.info("AOP日志:执行{}方法,注解描述:{}", signature.getMethodName(), annotation.value()); } }
执行效果
  • 调用list()delete()方法时,会触发beforeLog(),打印日志;
  • 调用save()方法时,因为无@LogAnnotation注解,不会触发切面;
  • 核心优势:无需关心方法的路径、参数、返回值,只要加了注解就拦截,新增需要日志的方法时,仅需加注解即可,无需修改切面代码。

三、@annotation 的进阶用法

1. 组合表达式(和 execution () 联用)

可以通过&&/||/!@annotationexecution()组合,实现更精准的匹配:

// 匹配:标注了@LogAnnotation 且 属于DeptService接口的方法 @Pointcut("@annotation(com.itheima.anno.LogAnnotation) && execution(* com.itheima.service.DeptService.*(..))") private void combinePt(){}
2. 切面中获取注解属性

在通知方法中可以获取注解的自定义属性,实现更灵活的逻辑:

@Before("logPt()") public void beforeLog(JoinPoint joinPoint) { // 1. 获取方法签名 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); // 2. 获取方法上的注解对象 LogAnnotation logAnno = method.getAnnotation(LogAnnotation.class); // 3. 获取注解属性值 String desc = logAnno.value(); // 4. 业务逻辑:比如根据注解属性区分日志类型 log.info("执行方法:{},日志描述:{}", method.getName(), desc); }
3. 匹配多个注解

通过||匹配多个注解标注的方法:

// 匹配标注了@LogAnnotation 或 @AuthAnnotation的方法 @Pointcut("@annotation(com.itheima.anno.LogAnnotation) || @annotation(com.itheima.anno.AuthAnnotation)") private void multiAnnoPt(){}

四、@annotation vs execution(核心区别)

维度@annotationexecution()
匹配依据方法上的注解标记方法的路径、返回值、参数、修饰符
灵活性高(新增拦截方法仅需加注解)低(新增方法需修改切入点表达式)
耦合度低(切面和业务方法解耦,靠注解关联)高(切面依赖方法的路径 / 参数等硬编码)
适用场景按业务场景标记(日志、权限、缓存)按方法路径 / 结构匹配(指定类 / 接口的方法)
示例拦截所有 @LogAnnotation 注解的方法拦截 DeptService 的 delete (Integer) 方法

五、Spring 内置注解的 @annotation 匹配

除了自定义注解,也可以匹配 Spring 内置注解(如 @GetMapping、@Transactional):

// 匹配所有标注了@Transactional的方法(监控事务方法执行) @Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)") private void transactionPt(){} // 匹配所有标注了@GetMapping的Controller方法(监控GET接口) @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)") private void getMappingPt(){}

六、注意事项

  1. 注解的 @Retention 必须是 RUNTIME:只有@Retention(RetentionPolicy.RUNTIME)的注解,才能在运行时被 AOP 识别,否则切入点会失效;
  2. 注解仅作用于方法@annotation只能匹配方法上的注解(注解的 @Target 需为ElementType.METHOD),无法匹配类 / 字段上的注解;
  3. 避免范围过大:如果自定义注解被大量方法标注,会导致 AOP 拦截范围过广,建议按业务模块拆分注解(如 @DeptLog、@EmpLog);
  4. 和 @within 的区别@annotation匹配 “方法上有注解” 的方法,@within匹配 “类上有注解” 的所有方法(比如类加 @Service,匹配该类所有方法)。

总结

  1. @annotation 核心作用:匹配所有标注了指定注解的方法,是 “面向注解” 的切入点定义方式;
  2. 核心优势:灵活、低耦合,新增拦截方法仅需加注解,无需修改切面;
  3. 典型场景:日志记录、权限校验、缓存控制、接口限流等按业务场景划分的拦截需求;
  4. 关键对比execution()是 “按方法结构匹配”,@annotation是 “按注解标记匹配”,生产中可根据需求选择或组合使用;
  5. 核心语法@Pointcut("@annotation(注解全限定类名)"),切面中可通过方法签名获取注解属性,实现个性化逻辑。

简单来说,@annotation让 AOP 从 “硬编码匹配方法” 变成了 “注解标记匹配方法”,是 Spring AOP 中更贴合业务开发的切入点方式。

再举一个@annotation的例子

@annotation和execution的区别是什么?

如何在@annotation中使用通配符?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1150124.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SiC碳化硅MOSFET微观动力学综述:开关瞬态全景解析

基本半导体B3M系列SiC碳化硅MOSFET微观动力学综述&#xff1a;开关瞬态全景解析BASiC Semiconductor基本半导体一级代理商倾佳电子&#xff08;Changer Tech&#xff09;是一家专注于功率半导体和新能源汽车连接器的分销商。主要服务于中国工业电源、电力电子设备和新能源汽车产…

稳如泰山:金融与政企专网为何偏爱 MPLS 二十年?

文章目录 效率:从“查字典”到“贴标签”的革命 安全:VRF 带来的“隐身术” 举例:金融机构 MPLS 企业广域网拓扑 SLA:RSVP-TE 的“金字招牌” 2026 年的现状:不是取代,而是“握手” 实战环节:华为设备 MPLS 基础配置 基础全局配置 接口使能 验证“标签转发”是否生效 结…

在 macOS 下用 mitmproxy 做 HTTP/HTTPS 抓包

大家好&#xff0c;我是jobleap.cn的小九。 在 macOS 下用 mitmproxy 做 HTTP/HTTPS 抓包&#xff0c;可以分成四步&#xff1a;安装、启动代理、配置系统/浏览器代理、安装并信任证书&#xff08;HTTPS 必须&#xff09;。 下面用最常用的 mitmweb 图形界面举例&#xff0c;顺…

【波束成形】双功能雷达与通信系统【含Matlab源码 14910期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;Matlab武动乾坤博客之家&#x1f49e;…

智能客服工单处理:精准QA提炼术

智能客服项目&#xff1a;将工单生成QA 提示词设计 目录智能客服项目&#xff1a;将工单生成QA 提示词设计一、提示词精准翻译&#xff08;中英对照专业术语校准&#xff09;1. Role and Objective&#xff08;角色与目标&#xff09;&#xff1a;2. General Approach&#xff…

医疗数据用JAX加速训练稳预测

&#x1f4dd; 博客主页&#xff1a;jaxzheng的CSDN主页 医疗数据科学新范式&#xff1a;JAX框架驱动的高效训练与稳健预测 目录引言&#xff1a;医疗AI的瓶颈与JAX的破局点 维度一&#xff1a;技术应用场景应用价值 维度二&#xff1a;技术能力映射——JAX的底层优势 维度三&…

关于 WEEX 唯客平台安全性的客观信息梳理

一、在信息密集环境中如何判断平台安全性在数字资产行业中&#xff0c;平台类型众多、信息来源复杂。用户在初次接触某一交易平台时&#xff0c;通过搜索其安全性、合规性与资金保障情况来进行核查&#xff0c;本身是一种理性的风险意识体现。但要区分合规运营的平台与存在风险…

ODC轨道数据中心算力电源架构与SiC碳化硅MOSFET应用研究报告

ODC轨道数据中心算力电源架构与SiC碳化硅MOSFET应用研究报告BASiC Semiconductor基本半导体一级代理商倾佳电子&#xff08;Changer Tech&#xff09;是一家专注于功率半导体和新能源汽车连接器的分销商。主要服务于中国工业电源、电力电子设备和新能源汽车产业链。倾佳电子聚焦…

BERT核心机制解析:BERT 是不是多头的,有没有位置编码,注意力机制;还是仅仅就是向量映射,BGE和BM25是什么,怎么使用

BERT 是不是多头的,有没有位置编码,注意力机制;还是仅仅就是向量映射 目录 BERT 是不是多头的,有没有位置编码,注意力机制;还是仅仅就是向量映射 1. 注意力机制(特别是“自注意力”) 2. 多头注意力 3. BERT 有位置信息:位置编码(在BERT中是“位置嵌入”) 整体的BERT…

收藏学习!AI如何克服“金鱼记忆“?从RAG到AgentRAG再到记忆增强系统详解

文章介绍了AI记忆机制的发展历程&#xff1a;从RAG&#xff08;检索增强生成&#xff09;到Agentic RAG&#xff08;引入智能代理提高检索效率&#xff09;&#xff0c;再到AI Memory&#xff08;读写机制实现个性化服务&#xff09;。这一演进使AI从"瞬时响应"转向&…

【波束成形】自适应MVDR波束成形和人工噪声无人机链路的运动感知物理层安全【含Matlab源码 14927期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;Matlab武动乾坤博客之家&#x1f49e;…

数通设备堆叠技术:iStack与CSS方案对比及应用选型

在数通网络架构中,堆叠技术是提升设备扩展性、可靠性与管理效率的核心方案,其中iStack(华为设备堆叠协议)与CSS(集群交换系统,华为高端设备堆叠方案)是业界主流的两种堆叠实现方式。结合业务口堆叠、堆叠卡堆叠、免配置堆叠等不同部署形态,二者在技术原理、性能特性、适…

从RAG的核心技术原理(语义表示、检索机制、知识融合)出发,解决“为什么检索不精准”“为什么知识融合不高效”等根本问题

从RAG的核心技术原理(语义表示、检索机制、知识融合)出发,解决“为什么检索不精准”“为什么知识融合不高效”等根本问题 目录 从RAG的核心技术原理(语义表示、检索机制、知识融合)出发,解决“为什么检索不精准”“为什么知识融合不高效”等根本问题 简单rag 简介 一、嵌…

【波束成形】基于matlab双功能雷达与通信系统【含Matlab源码 14910期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到海神之光博客之家&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49…

【雷达回波】电离层回波方向估计HF地表波雷达【含Matlab源码 14911期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;Matlab武动乾坤博客之家&#x1f49e;…

如何高效实现图片智能抠图?试试科哥CV-UNet大模型镜像

如何高效实现图片智能抠图&#xff1f;试试科哥CV-UNet大模型镜像 在图像处理领域&#xff0c;智能抠图&#xff08;Image Matting&#xff09;是实现高质量前景提取的核心技术&#xff0c;广泛应用于电商产品图制作、人像后期、虚拟背景替换等场景。传统手动抠图耗时耗力&…

零基础玩转语音识别|科哥定制FunASR镜像一键部署教程

零基础玩转语音识别&#xff5c;科哥定制FunASR镜像一键部署教程 1. 引言&#xff1a;为什么选择科哥定制版 FunASR&#xff1f; 在当前 AI 大模型与智能语音技术快速发展的背景下&#xff0c;语音识别&#xff08;ASR&#xff09; 已成为智能客服、会议记录、字幕生成、语音…

移远SDK ql_app_pre_init.c文件解析

代码 /** @fileql_app_pre_init.c@briefTODO*//*================================================================Copyright (c) 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.Quectel Wireless Solution Proprietary and Confidential. =============…

【波束成形】基于matlab自适应MVDR波束成形和人工噪声无人机链路的运动感知物理层安全【含Matlab源码 14927期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到海神之光博客之家&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49…

如何快速实现图片智能抠图?CV-UNet大模型镜像开箱即用

如何快速实现图片智能抠图&#xff1f;CV-UNet大模型镜像开箱即用 随着AI在图像处理领域的深入应用&#xff0c;智能抠图&#xff08;Image Matting&#xff09; 已从传统手动操作演变为自动化、高精度的AI驱动流程。尤其在电商、设计、影视后期等场景中&#xff0c;高效精准地…