切入点
Spring 的切入点是一种 AOP 中的基本概念,它定义了在哪些连接点上进行通知(Advice)的匹配规则。Spring AOP 支持基于正则表达式、AspectJ 注解等多种方式定义切入点。示例如下:
<bean id="around" class="world.xuewei.proxy.Around"/> <!-- 配置动态代理 --> <aop:config> <!-- 所有方法都作为切入点,加入额外功能 --> <aop:pointcut id="p1" expression="execution(* *(..))"/> <!-- 整合组装 --> <aop:advisor advice-ref="around" pointcut-ref="p1"/> </aop:config>
表达式的规则为
execution(返回类型 包名.类名.方法名(参数列表))
- 返回类型:表示方法的返回类型或通配符。
*
:匹配任意返回类型。void
:匹配 void 返回类型。java.lang.String
:匹配具体的返回类型,如果是java.lang
包下的可以省略包路径,否则需要写明。
- 包名:表示方法所在的包名或通配符。
*
:匹配所有包。com.example.service
:匹配指定的包名。com.example.service.*
:匹配 com.example.service 包下的所有类。com.example.service..*.*
:匹配 com.example.service 包以及子包下的所有类。com.example.*.service
:匹配 com.example 及其子包中的所有 service 包下的类。
- 类名:表示方法所在的类名或通配符。
*
:匹配所有类。UserService
:匹配指定的类名。*Service
:匹配以 Service 结尾的所有类。com.example..*.*Service
:匹配 com.example 及其子包中以 Service 结尾的类。
- 方法名:表示方法的名称或通配符。
*
:匹配所有方法。getUser
:匹配指定的方法名。get*
:匹配以 get 开头的所有方法名。*User
:匹配以 User 结尾的所有方法名。
- 参数列表:表示方法的参数类型或通配符。
()
:匹配没有参数的方法。(..)
:匹配任意参数个数和类型的方法。(java.lang.String)
:匹配只有一个String类型参数的方法。如果是java.lang
包下的可以省略包路径,否则需要写明。(java.lang.String, *)
:匹配第一个参数为String类型,第二个参数为任意类型的方法。如果是java.lang
包下的可以省略包路径,否则需要写明。(java.lang.String, ..)
:匹配第一个参数为String类型,后面任意多个(可包含没有)参数。如果是java.lang
包下的可以省略包路径,否则需要写明。
通过组合以上不同的部分,可以构建出灵活的切入点表达式,以满足各种不同的 AOP 需求。
需要注意的是,在编写切入点表达式时,可以使用通配符 *
匹配任意字符(但不包括路径分隔符/),使用 ..
匹配任意多层路径。同时,切入点表达式不区分大小写。
切入点函数
切入点函数用于执行切入点表达式,execution 可以提供非常丰富的切入点写法,但是写起来非常的麻烦。
- execution:匹配方法执行的连接点,支持通配符、正则表达式和类型限定符等。
- 示例:
execution(* com.example.service.*.*(..))
- within:匹配指定类型内部的所有连接点。主要用于包、类切入点表达式的匹配。
- 示例:
within(com.example.service.*)
- this:匹配当前代理对象的实例类型。
- 示例:
this(com.example.service.AServiceImpl)
- target:匹配目标对象类的类型。
- 示例:
target(com.example.service.BService)
- args:匹配传入方法的参数类型。
- 示例:
args(java.lang.String, ..)
- @annotation:匹配使用特定注解修饰的方法。
- 示例:
@annotation(org.springframework.transaction.annotation.Transactional)
- bean:匹配指定名称的bean。
- 示例:
bean(someBean)
切入点函数的逻辑运算
整合多个切⼊点函数⼀起配合⼯作,完成更为复杂的需求。
and
execution(* login(..)) and execution(* register(..))
or
execution(* login(..)) or execution(* register(..))