Spring切入点表达式常用写法

本文介绍 Spring AOP 中的切入点表达式用法,包括 execution、within、this、target、args 等表达式的示例及通配符的使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下文档来自Spring中文开发指南2.5文档,由满江红开源组织翻译:
 
Spring AOP 用户可能会经常使用  execution切入点指示符。执行表达式的格式如下:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)
          throws-pattern?)
除了返回类型模式(上面代码片断中的ret-type-pattern),名字模式和参数模式以外, 所有的部分都是可选的。返回类型模式决定了方法的返回类型必须依次匹配一个连接点。 你会使用的最频繁的返回类型模式是 *,它代表了匹配任意的返回类型。 一个全限定的类型名将只会匹配返回给定类型的方法。名字模式匹配的是方法名。 你可以使用 *通配符作为所有或者部分命名模式。 参数模式稍微有点复杂: ()匹配了一个不接受任何参数的方法, 而 (..)匹配了一个接受任意数量参数的方法(零或者更多)。 模式 (*)匹配了一个接受一个任何类型的参数的方法。 模式 (*,String)匹配了一个接受两个参数的方法,第一个可以是任意类型, 第二个则必须是String类型。更多的信息请参阅AspectJ编程指南中  语言语义的部分。
下面给出一些通用切入点表达式的例子。
  • 任意公共方法的执行:
    execution(public * *(..))
  • 任何一个名字以“set”开始的方法的执行:
    execution(* set*(..))
  • AccountService接口定义的任意方法的执行:
    execution(* com.xyz.service.AccountService.*(..))
  • 在service包中定义的任意方法的执行:
    execution(* com.xyz.service.*.*(..))
  • 在service包或其子包中定义的任意方法的执行:
    execution(* com.xyz.service..*.*(..))
  • 在service包中的任意连接点(在Spring AOP中只是方法执行):
    within(com.xyz.service.*)
  • 在service包或其子包中的任意连接点(在Spring AOP中只是方法执行):
    within(com.xyz.service..*)
  • 实现了 AccountService接口的代理对象的任意连接点 (在Spring AOP中只是方法执行):
    this(com.xyz.service.AccountService)
    'this'在绑定表单中更加常用:- 请参见后面的通知一节中了解如何使得代理对象在通知体内可用。
  • 实现 AccountService接口的目标对象的任意连接点 (在Spring AOP中只是方法执行):
    target(com.xyz.service.AccountService)
    'target'在绑定表单中更加常用:- 请参见后面的通知一节中了解如何使得目标对象在通知体内可用。
  • 任何一个只接受一个参数,并且运行时所传入的参数是 Serializable 接口的连接点(在Spring AOP中只是方法执行)
    args(java.io.Serializable)
    'args'在绑定表单中更加常用:- 请参见后面的通知一节中了解如何使得方法参数在通知体内可用。
    请注意在例子中给出的切入点不同于  execution(* *(java.io.Serializable)): args版本只有在动态运行时候传入参数是Serializable时才匹配,而execution版本在方法签名中声明只有一个  Serializable类型的参数时候匹配。
  • 目标对象中有一个  @Transactional 注解的任意连接点 (在Spring AOP中只是方法执行)
    @target(org.springframework.transaction.annotation.Transactional)
    '@target'在绑定表单中更加常用:- 请参见后面的通知一节中了解如何使得注解对象在通知体内可用。
  • 任何一个目标对象声明的类型有一个  @Transactional 注解的连接点 (在Spring AOP中只是方法执行):
    @within(org.springframework.transaction.annotation.Transactional)
    '@within'在绑定表单中更加常用:- 请参见后面的通知一节中了解如何使得注解对象在通知体内可用。
  • 任何一个执行的方法有一个  @Transactional 注解的连接点 (在Spring AOP中只是方法执行)
    @annotation(org.springframework.transaction.annotation.Transactional)
    '@annotation'在绑定表单中更加常用:- 请参见后面的通知一节中了解如何使得注解对象在通知体内可用。
  • 任何一个只接受一个参数,并且运行时所传入的参数类型具有 @Classified 注解的连接点(在Spring AOP中只是方法执行)
    @args(com.xyz.security.Classified)
    '@args'在绑定表单中更加常用:- 请参见后面的通知一节中了解如何使得注解对象在通知体内可用。
  • 任何一个在名为' tradeService'的Spring bean之上的连接点 (在Spring AOP中只是方法执行):
    bean(tradeService)
  • 任何一个在名字匹配通配符表达式' *Service'的Spring bean之上的连接点 (在Spring AOP中只是方法执行):
    bean(*Service)

组合pointcut表达式

可以使用 && 、|| 、! 组合pointcut表达式。

execution格式

execution(

可见性(可选) —— 使用public、protected、private指定可见性。也可以为*,表示任意可见性

返回值类型(必须) —— 指定返回值类型

声明类型(可选)——  java包

方法名(参数模式)(必须) —— 方法名称,和方法接收的参数

异常模式(可选) —— 指定方法签名中是否存在异常类型

)

在pointcut表达式中可以使用 * 、.. 、 +等通配符。

* :表示若干字符(排除 . 在外)

.. :表示若干字符(包括 . 在内)

+ :表示子类 ,比如Info+ 表示Info类及其子类


<think>我们正在讨论SpringAOP中的切入点表达式语法格式。根据用户提供的引用和之前的上下文,我们知道切入点表达式用于描述哪些方法需要被增强(即应用通知)。引用[3]和[4]明确提到了切入点表达式的标准格式。我们将结合这些引用来回答。切入点表达式标准格式:动作关键字(访问修饰符返回值包名.类/接口名.方法名(参数)异常名)但是,在实际使用中,我们通常不会写出所有部分,而是根据需要使用通配符和省略一些可选部分。详细解析:1.动作关键字(最常用的是execution):-表示匹配方法的执行。例如:`execution(...)`2.访问修饰符(可选):-表示方法的访问修饰符,如public,private等。可以省略,省略时表示匹配所有访问权限。3.返回值(必填):-表示方法的返回值类型。使用*可以表示任意返回类型。4.包名.类/接口名.方法名(必填):-指定具体的方法位置。包名可以使用`..`来表示当前包及其子包。类名和方法名可以使用通配符*。5.参数(必填):-方法的参数列表。使用`..`表示任意多个参数(包括0个),也可以使用`*`表示一个任意类型的参数。6.异常名(可选):-方法抛出的异常类型。通常很少使用。示例(来自引用[4]):-精确匹配:`execution(voidcom.itheima.dao.BookDao.update())`-使用通配符:`execution(voidcom.itheima.dao.impl.BookDaoImpl.update())`通用写法技巧(参考引用):-使用通配符`*`:匹配任意字符(除包名分隔符和类名分隔符外)。-例如:`execution(*com.example.service.*.*(..))`表示匹配com.example.service包下任意类的任意方法,参数任意,返回值为任意类型。-使用`..`:在包路径中表示当前包及其子包;在参数列表位置表示任意数量任意类型的参数。-例如:`execution(*com.example..*.*(..))`表示匹配com.example包及其所有子包下的任意类的任意方法。注意事项:-切入点表达式通常以`execution`关键字开始,后面紧跟括号,括号内描述方法签名。-表达式中的各部分之间用空格隔开,但实际上空格并不是强制要求,但为了清晰,建议在关键部分之间加空格。举例:1.匹配所有public方法:```java@Pointcut("execution(public**(..))")```2.匹配指定包下所有方法(不包含子包):```java@Pointcut("execution(*com.example.service.*.*(..))")```3.匹配指定包及其子包下所有类的所有方法:```java@Pointcut("execution(*com.example..*.*(..))")```4.匹配特定类的所有方法:```java@Pointcut("execution(*com.example.service.UserService.*(..))")```5.匹配方法名为特定名称的方法:```java@Pointcut("execution(**..find*(..))")```参考用户提供的引用,我们可以在回答中引用相应的内容。最后,按照用户要求生成相关问题。注意:由于用户要求使用中文,并且使用正确的LaTeX格式(但在这个问题中似乎不太需要数学公式,所以主要注意代码块和引用标识)。</think> ### Spring AOP 切入点表达式语法格式 Spring AOP 的切入点表达式用于精确描述需要应用通知(Advice)的方法位置。以下是完整的语法规范: #### 📐 标准语法格式 ```java 动作关键字(访问修饰符 返回值 包名.类名.方法名(参数类型) 异常类型) ``` #### 📌 核心组成部分 1. **动作关键字**(必需) 最常用的是 `execution`,表示匹配方法执行 2. **访问修饰符**(可选) 如 `public`、`private` 等,省略时匹配所有访问权限 示例:`public` 或省略 3. **返回值类型**(必需) - 精确类型:`void`, `String`, `int` - 通配符:`*`(匹配任意返回值类型) 示例:`*` 或 `void` 4. **类路径与方法名**(必需) - 包名:可使用 `..` 表示当前包及其子包 - 类名:可使用 `*` 通配符 - 方法名:可使用 `*` 通配符 示例:`com.service..*Service.*(..)` 5. **参数列表**(必需) - `()`:匹配无参方法 - `(类型)`:精确匹配单参数 - `(..)`:匹配任意参数(数量不限) - `(*, String)`:匹配两个参数(第一个任意类型,第二个String) 示例:`(..)` 或 `(String, int)` 6. **异常类型**(可选) 如 `throws IOException`,通常可省略[^3] #### 🔧 通配符使用技巧 | 通配符 | 作用 | 示例 | 效果 | |--------|-----------------------|----------------------|--------------------------| | `*` | 匹配单个单词 | `*.getUser()` | 任意类的getUser方法 | | `..` | 匹配包路径或多参数 | `com..service.*(..)` | com包下所有service类的任意方法 | | `+` | 匹配子类/实现类 | `com.BaseService+` | BaseService及其子类 | #### 🧪 实际用例 1. **匹配指定包下所有方法** ```java @Pointcut("execution(* com.example.service.*.*(..))") ``` 2. **匹配特定类的无参方法** ```java @Pointcut("execution(void com.dao.BookDao.update())") ``` 3. **匹配子包中的方法** ```java @Pointcut("execution(* com..repository.*.find*(..))") ``` 4. **匹配抛出异常的方法** ```java @Pointcut("execution(* *(..) throws IOException)") ``` #### 💡 优化建议 1. 优先使用 `..` 简化包路径描述 2. 用 `*` 替代不关心的元素(如返回值) 3. 参数使用 `(..)` 避免过度限定 4. 将复杂表达式拆分为多个`@Pointcut`组合[^2] > 📌 关键特性:Spring 使用 AspectJ 的切入点语法,但在实现上是基于代理的轻量级方案[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值