Spring AOP 切点表达式与自定义注解实战指南
系列导航:前两篇解决了 AOP 是什么、通知怎么执行。本篇聚焦切点表达式:如何用 execution 精准或模糊匹配方法,以及当方法毫无规律时,如何用自定义注解 + @annotation 精准拦截。
1.execution表达式:从精准到模糊匹配
语法:
execution(<访问修饰符> <返回类型> <包名.类名.方法(方法参数)> <异常>)
其中访问修饰符和异常可以省略。
假设目标方法是:
public String com.example.demo.controller.TestController.t1()
逐步推演匹配范围:
| 表达式 | 匹配范围 |
|---|---|
execution(public String com.example.demo.controller.TestController.t1()) | 最精准匹配 |
execution(String com.example.demo.controller.TestController.t1()) | 省略访问修饰符 |
execution(* com.example.demo.controller.TestController.t1()) | 任意返回值类型 |
execution(* com.example.demo.controller.TestController.*()) | TestController 下所有无参方法 |
execution(* com.example.demo.controller.TestController.*(..)) | TestController 下所有方法 |
execution(* com.example.demo.controller.*.*(..)) | controller 包下所有类的所有方法 |
execution(* com..TestController.*(..)) | 任意包下的 TestController |
execution(* com.example.demo..*.*(..)) | com.example.demo 及所有子包下所有类的所有方法 |
关键总结:
*:匹配一个元素,例如一个包、一个类、一个参数。..:匹配多个元素,例如多层包、任意个参数。
2. 痛点推演:当方法毫无规律时怎么办?
假设现在有两个类:
TestController下的t1()UserController下的u1()
现在只想拦截这两个方法,其他方法如 t2、u2 一律不拦截。它们的方法名、所在包、参数可能都毫无规律。
如果用 execution,可能要写成:
execution(* ...t1()) || execution(* ...u1())
如果有几十个无规律的方法,表达式会极其臃肿,后续也难以维护。
3. 方案:自定义注解 +@annotation表达式
推理:既然规则无法用通配符描述,那能不能给需要拦截的方法“打个标签”,AOP 专门拦截带有这个标签的方法?
步骤:
- 编写自定义注解。
- 在需要拦截的方法上添加该注解。
- 在切面中使用
@annotation,告诉 AOP:看到这个注解就拦截。
第一步:定义注解
@Target(ElementType.METHOD) // 限制该注解只能加在方法上
@Retention(RetentionPolicy.RUNTIME) // 注解保留到运行期,AOP 才能在运行时通过反射读取
public @interface MyAspect {
}@Retention 的三种取值:
SOURCE:仅存在于源码,编译后丢弃,例如@SuppressWarnings、Lombok 的@Data。CLASS:存在于源码和字节码,运行时丢弃。RUNTIME:存在于源码、字节码和运行时,只有它才能让 AOP 在运行时读取注解。
第二步:编写切面
@Aspect
@Component
public class MyAspectDemo {
// 切点表达式换成 @annotation,指向自定义注解的全限定名
@Before("@annotation(com.example.demo.aspect.MyAspect)")
public void before(){
log.info("MyAspect -> before ...");
}
}第三步:在目标方法上打标签
// TestController
@MyAspect
@RequestMapping("/t1")
public String t1() { return "t1"; }
@RequestMapping("/t2")
public String t2() { return "t2"; } // 没加注解,AOP 不拦截4. 流程变化与结果推演
- 请求
/test/t1时,Spring AOP 发现t1上有@MyAspect,触发切面逻辑,打印before ...。 - 请求
/test/t2时,t2上没有注解,AOP 直接放行,切面逻辑完全不执行。
@annotation 拦截流程

execution 与 @annotation 的选择

到此这篇关于Spring AOP 切点表达式与自定义注解实战指南的文章就介绍到这了,更多相关Spring AOP 切点表达式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
SpringMVC @ResponseBody 415错误处理方式
这篇文章主要介绍了SpringMVC @ResponseBody 415错误处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-11-11
spring boot里增加表单验证hibernate-validator并在freemarker模板里显示错误信息(推
这篇文章主要介绍了spring boot里增加表单验证hibernate-validator并在freemarker模板里显示错误信息的相关资料,需要的朋友可以参考下2018-01-01
java.lang.UnsupportedOperationException的问题解决
本文主要介绍了java.lang.UnsupportedOperationException的问题解决,该错误表示调用的方法不被支持或不可用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2024-07-07


最新评论