Spring AOP 切点表达式与自定义注解实战指南

 更新时间:2026年11月10日 09:31:49   作者:驭渊的小故事  
本文深入讲解Spring AOP中切点表达式的应用,重点对比execution的精准/模糊匹配局限性,并针对方法命名与包结构无规律的痛点,提出基于@annotation的自定义注解方案,感兴趣的朋友一起看看吧

系列导航:前两篇解决了 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 切点表达式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用SpringBoot发送邮箱验证码的简单实现

    使用SpringBoot发送邮箱验证码的简单实现

    这篇文章主要介绍了使用SpringBoot发送邮箱验证码的简单实现,咱们今天来讲使用QQ邮箱来发送和接收验证码,首先来介绍一下它在SpringBoot项目中的具体应用,需要的朋友可以参考下
    2023-04-04
  • java MD5加密实现代码

    java MD5加密实现代码

    这篇文章主要为大家详细介绍了java MD5加密实现过程,为大家分享了MD5加密代码,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • SpringMVC @ResponseBody 415错误处理方式

    SpringMVC @ResponseBody 415错误处理方式

    这篇文章主要介绍了SpringMVC @ResponseBody 415错误处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Java实现Executors类创建常见线程池

    Java实现Executors类创建常见线程池

    本文主要介绍了Java实现Executors类创建常见线程池,在Java中,可以通过Executors工厂类提供四种常见类型的线程池,下面就来介绍一下这四种的方法实现,感兴趣的可以了解一下
    2023-11-11
  • MyBatis环境搭建和基本操作步骤

    MyBatis环境搭建和基本操作步骤

    MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射,本文给大家介绍MyBatis环境搭建和基本操作大全,感兴趣的朋友跟随小编一起看看吧
    2026-08-08
  • Spring mvc服务端数据校验实现流程详解

    Spring mvc服务端数据校验实现流程详解

    这篇文章主要介绍了Spring mvc服务端数据校验实现流程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • spring boot里增加表单验证hibernate-validator并在freemarker模板里显示错误信息(推荐)

    spring boot里增加表单验证hibernate-validator并在freemarker模板里显示错误信息(推

    这篇文章主要介绍了spring boot里增加表单验证hibernate-validator并在freemarker模板里显示错误信息的相关资料,需要的朋友可以参考下
    2018-01-01
  • IDEA 控制台中文乱码4种解决方案

    IDEA 控制台中文乱码4种解决方案

    IntelliJ IDEA 如果不进行相关设置,可能会导致控制台中文乱码、配置文件中文乱码等问题,本文主要介绍了IDEA控制台中文乱码4种解决方案,具有一定的参考价值,感兴趣的可以了解一下
    2024-07-07
  • Springboot自动加载配置的原理解析

    Springboot自动加载配置的原理解析

    Springboot遵循“约定优于配置”的原则,使用注解对一些常规的配置项做默认配置,减少或不使用xml配置,让你的项目快速运行起来,这篇文章主要给大家介绍了关于Springboot自动加载配置原理的相关资料,需要的朋友可以参考下
    2021-10-10
  • java.lang.UnsupportedOperationException的问题解决

    java.lang.UnsupportedOperationException的问题解决

    本文主要介绍了java.lang.UnsupportedOperationException的问题解决,该错误表示调用的方法不被支持或不可用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-07-07

最新评论