当前位置: 首页 > ds >正文

小结:Spring AOP 切点表达式

Spring AOP 切点表达式(Pointcut Expression)


一、切点表达式概述

切点表达式 是 Spring AOP 用于定义哪些方法(或连接点)需要被拦截的规则,主要基于 AspectJ 切点表达式语言。Spring AOP 仅支持方法级别的切点(相比 AspectJ 的字段、构造器等更广泛支持),通过表达式指定目标方法,结合通知(Advice)实现横切逻辑。

  • 作用:精确匹配需要应用切面逻辑的方法。
  • 使用场景:日志记录、事务管理、权限检查等。
  • 表达式解析器:Spring AOP 使用 AspectJ 的切点表达式解析器(需要 spring-aspects 依赖)。

二、切点表达式语法

AspectJ 切点表达式的通用语法为:

execution(modifiers-pattern? return-type-pattern declaring-type-pattern? method-name-pattern(param-pattern) throws-pattern?)
  • modifiers-pattern(可选):方法修饰符,如 publicprivate
  • return-type-pattern:方法返回值类型,如 void*(任意类型)。
  • declaring-type-pattern(可选):声明方法的类或包,如 com.example.service.*
  • method-name-pattern:方法名称模式,如 add*
  • param-pattern:方法参数模式,如 (…)(任意参数)。
  • throws-pattern(可选):异常类型,如 throws IOException

通配符:

  • *:匹配任意字符(用于方法名、类名、返回值等)。
  • :匹配任意数量的参数或包路径。
  • +:匹配指定类及其子类。

三、常用切点表达式关键字

Spring AOP 主要支持以下 AspectJ 切点指示符(Pointcut Designators):

  1. execution
    • 匹配方法执行的连接点,是 Spring AOP 最常用的切点指示符。
    • 示例:
      • execution(* com.example.service.*.*(…)):匹配 com.example.service 包下所有类的所有方法,任意返回值,任意参数。
      • execution(public void com.example.UserService.add*(…)):匹配 UserService 类中以 add 开头的公共方法,返回值为 void
      • execution(* com.example…*.*(String, int)):匹配 com.example 包及其子包下所有类的接收 Stringint 参数的方法。
  2. within
    • 匹配指定类型或包内的所有方法。
    • 示例:
      • within(com.example.service.*):匹配 com.example.service 包下所有类的所有方法。
      • within(com.example…*):匹配 com.example 包及其子包下所有类的所有方法。
  3. @annotation
    • 匹配带有特定注解的方法。
    • 示例:
      • @annotation(org.springframework.transaction.annotation.Transactional):匹配带有 @Transactional 注解的方法。
      • @annotation(com.example.MyCustomAnnotation):匹配带有自定义注解的方法。
  4. args
    • 匹配方法参数类型。
    • 示例:
      • args(String, …):匹配第一个参数为 String 的方法,后面参数任意。
      • args(String, int):匹配参数严格为 (String, int) 的方法。
  5. this
    • 匹配代理对象的类型(通常是接口类型或类类型)。
    • 示例:
      • this(com.example.UserService):匹配代理对象是 UserService 类型的连接点。
  6. target
    • 匹配目标对象的类型。
    • 示例:
      • target(com.example.UserService):匹配目标对象是 UserService 类型的连接点。
  7. @target
    • 匹配目标对象带有特定注解的类型。
    • 示例:
      • @target(org.springframework.stereotype.Service):匹配带有 @Service 注解的类中的方法。
  8. @args
    • 匹配方法参数带有特定注解的场景。
    • 示例:
      • @args(com.example.MyAnnotation):匹配方法参数带有 @MyAnnotation 注解的方法。
  9. bean(Spring 特有):
    • 匹配特定 Spring Bean 名称。
    • 示例:
      • bean(userService):匹配 ID 为 userService 的 Bean 的所有方法。
      • bean(*Service):匹配以 Service 结尾的 Bean 的所有方法。

四、切点表达式的组合

切点表达式可以通过逻辑运算符组合,增强匹配灵活性:

  • &&(与):两个条件都满足。
    • **示例:execution(* com.example.service.*.*(…)) && @annotation(org.springframework.transaction.annotation.Transactional) **
      • 匹配 com.example.service 包下带有 @Transactional 注解的方法。
  • ||(或):任一条件满足。
    • **示例:**execution(* com.example.service.*.*(…)) || execution(* com.example.controller.*.*(…))
      • 匹配 servicecontroller 包下的方法。
  • !(非):取反。
    • **示例:**execution(* com.example.service.*.*(…)) && !execution(* com.example.service.UserService.*(…))
      • 匹配 service 包下除 UserService 类之外的所有方法。

五、常用切点表达式示例

以下是一些常见的切点表达式及其用途:

  1. 匹配所有方法
    java

    execution(* *.*(..))
    
    • 匹配所有类的所有方法,任意返回值,任意参数。
  2. 匹配特定包下所有方法
    java

    execution(* com.example.service.*.*(..))
    
    • 匹配 com.example.service 包下所有类的所有方法。
  3. 匹配特定类的方法
    java

    execution(* com.example.UserService.*(..))
    
    • 匹配 UserService 类中的所有方法。
  4. 匹配特定方法名前缀
    java

    execution(* com.example.UserService.add*(..))
    
    • 匹配 UserService 类中以 add 开头的方法。
  5. 匹配特定返回值类型
    java

    execution(String com.example.*.*(..))
    
    • 匹配 com.example 包下返回值类型为 String 的方法。
  6. 匹配特定参数类型
    java

    execution(* com.example.*.*(String, int))
    
    • 匹配参数类型为 (String, int) 的方法。
  7. 匹配注解方法
    java

    @annotation(org.springframework.web.bind.annotation.GetMapping)
    
    • 匹配带有 @GetMapping 注解的 Controller 方法。
  8. 匹配特定 Bean
    java

    bean(userService)
    
    • 匹配 ID 为 userService 的 Bean 的所有方法。
  9. 匹配子包
    java

    within(com.example..*)
    
    • 匹配 com.example 包及其子包下所有类的所有方法。

六、切点表达式的配置方式

**1. **XML 配置

在 XML 中通过 aop:pointcut 定义切点:

xml

<aop:config><aop:aspect id="logAspect" ref="loggingAspect"><aop:pointcut id="logPointcut" expression="execution(* com.example.service.*.*(..))"/><aop:before pointcut-ref="logPointcut" method="logBefore"/></aop:aspect>
</aop:config>

**2. **注解配置

使用 @Pointcut 注解定义切点:

java

@Aspect
@Component
public class LoggingAspect {@Pointcut("execution(* com.example.service.*.*(..))")public void logPointcut() {}@Before("logPointcut()")public void logBefore() {System.out.println("Before method execution");}
}
  • @Pointcut 方法通常为空,仅用于定义切点,供其他通知引用。
  • 确保启用 AOP 注解支持:@EnableAspectJAutoProxy**。**

七、注意事项

  1. 精确性
    • 切点表达式应尽量精确,避免匹配过多无关方法,影响性能。
    • 例如,execution(* *.*(…)) 过于宽泛,可能导致不必要的代理开销。
  2. Spring AOP 限制
    • 仅支持方法级别的切点,无法拦截字段访问或构造器。
    • 内部方法调用(this.method())不会触发代理,切面逻辑可能失效。
  3. 性能考虑
    • 复杂的切点表达式或大量匹配方法可能增加解析和代理开销。
    • 使用 beanwithin 限制范围以提高效率。
  4. 调试技巧
    • 使用日志或调试工具验证切点匹配的方法。
    • 确保表达式语法正确,错误表达式会导致匹配失败。
  5. 依赖
    • 注解方式需要 spring-aspects 依赖:
      xml

      <dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version>
      </dependency>
      

八、总结

切点表达式 是 Spring AOP 的核心,用于定义需要拦截的方法。基于 AspectJ 表达式语言,Spring AOP 提供灵活的匹配规则,常用关键字包括 executionwithin@annotationbean 等。通过 &&||! 组合表达式,可以实现复杂的匹配逻辑。

核心要点:

  • 语法execution(modifiers? return-type declaring-type? method-name(param) throws?)
  • 常用指示符
    • execution:匹配方法签名。
    • within:匹配类或包。
    • @annotation:匹配注解方法。
    • bean:匹配特定 Spring Bean。
  • 组合方式:使用 &&||! 实现复杂匹配。
  • 配置方式:XML(aop:pointcut)或注解(@Pointcut)。
  • 注意事项:确保表达式精确、注意 Spring AOP 的方法级别限制、优化性能。
http://www.xdnf.cn/news/13921.html

相关文章:

  • 中国人工智能社区发展研究报告(2025)
  • MySQL 索引类型及其必要性与优点
  • 【QT】 QGraphicsItem 获取点坐标的几种方法
  • error report
  • 5种常见的网络保密通信协议
  • 【Linux】regmap子系统
  • 智慧工厂物联网解决方案:纺织厂边缘计算网关应用
  • 图像处理控件Aspose.Imaging教程:图像处理控件Aspose.Imaging教程:在Java中构建 SVG 图像调整器
  • vanna多表关联的实验
  • 将idea的目录结构以文本导出
  • MySQL 8.0的数据库root用户默认无法远程登录,需要修改root的远程授权
  • 使用AkShare获取大A列表
  • ( github actions + workflow 03 ) 手动添加 token, 防止权限不够
  • 运营商实名验证接口如何用Python实现调用?
  • 新疆大学具身导航新范式!DOPE:基于双重对象感知增强网络的视觉语言导航
  • golang -- map实现原理
  • 单片机队列功能模块的实战和应用
  • Elasticsearch的数据同步
  • 在线机考|2025年华为暑期实习春招秋招编程题(最新)——第2题_网络整改
  • 基于mapreduce的气候分析系统
  • Dify实战案例:AI邮件批量发送器!
  • Unit 3 Q-Learning 简介
  • 06-Python流程控制
  • [论文阅读] 人工智能 | ComfyUI-R1: Exploring Reasoning Models for Workflow Generation
  • JDBC接口开发指南
  • kali系统 windows Linux靶机入侵演练
  • 《Qt5.14.1与Mingw C++:打造可发布程序的技术之旅》
  • 实时监控、秒级决策:镜舟科技如何重塑融资融券业务数据处理模式
  • @SchedulerLock处理Spring Task在分布式环境下的重复执行问题
  • Transformer模型详解