Spring 中的切点表达式介绍

2023-11-17

Spring 中的切点表达式介绍

翻译原文链接 Introduction to Pointcut Expressions in Spring

1. 概述

在本教程中,我们将讨论 Spring AOP 切点表达式语言。

In this tutorial we will discuss the Spring AOP pointcut expression language.

我们将首先介绍一些在面向切面编程中使用的术语。连接点是程序执行的一个步骤,例如方法的执行或异常的处理。在 Spring AOP 中,一个连接点总是代表一个方法的执行。切点是匹配连接点的谓词,切点表达式语言 是一种以编程方式描述切点的方式。

We will first introduce some terminology used in aspect-oriented programming. A join point is a step of the program execution, such as the execution of a method or the handling of an exception. In Spring AOP, a join point always represents a method execution. A pointcut is a predicate that matches the join points and a pointcut expression language is a way of describing pointcuts programmatically.

2. 用法

切点表达式可以作为 @Pointcut 注解的值出现:

A pointcut expression can appear as a value of the @Pointcut annotation:

@Pointcut("within(@org.springframework.stereotype.Repository *)")
public void repositoryClassMethods() {}

方法声明称为切点签名。它提供了一个名称,通知注解可以使用该名称来引用该切点。

The method declaration is called the pointcut signature. It provides a name that can be used by advice annotations to refer to that pointcut.

@Around("repositoryClassMethods()")
public Object measureMethodExecutionTime(ProceedingJoinPoint pjp) throws Throwable {
    // ...
}

切点表达式也可以作为 aop:pointcut 标签的表达式属性的值出现:

A pointcut expression could also appear as the value of the expression property of an aop:pointcut tag:

<aop:config>
    <aop:pointcut id="anyDaoMethod" 
         expression="@target(org.springframework.stereotype.Repository)"/>
</aop:config>

3. 切点指示符

切点表达式以切点指示符 (PCD) 开头,它是告诉 Spring AOP 匹配什么的关键字。有几个切点指示符,例如方法的 执行类型方法参数注解

A pointcut expression starts with a pointcut designator (PCD), which is a keyword telling Spring AOP what to match. There are several pointcut designators, such as the execution of a method, a type, method arguments, or annotations.

3.1 execution

Spring 中主要的切点指示符是 execution,它匹配方法执行连接点。

The primary Spring PCD is execution, which matches method execution join points.

@Pointcut("execution(public String com.baeldung.pointcutadvice.dao.FooDao.findById(Long))")

此示例切点将与 FooDao 类的 findById 方法的执行完全匹配。这(虽然)有效,但不是很灵活。假设我们想要匹配 FooDao 类的所有方法,这些方法可能具有不同的 签名返回类型参数。为了实现这一点,我们可以使用通配符:

This example pointcut will match exactly the execution of findById method of the FooDao class. This works, but it is not very flexible. Suppose we would like to match all the methods of the FooDao class, which may have different signatures, return types, and arguments. To achieve this we may use wildcards:

@Pointcut("execution(* com.baeldung.pointcutadvice.dao.FooDao.*(..))")

这里第一个通配符匹配任何返回值,第二个匹配任何方法名称,(…) 模式匹配任意数量的参数(零个或多个)。

Here the first wildcard matches any return value, the second matches any method name, and the (…) pattern matches any number of parameters (zero or more).

3.2 within

获得与上一节相同结果的另一种方法是使用 within 切点知识符,它将匹配限制为某些类型的连接点。

Another way to achieve the same result from the previous section is by using the within PCD, which limits matching to join points of certain types.

@Pointcut("within(com.baeldung.pointcutadvice.dao.FooDao)")

我们还可以匹配 com.baeldung 包或子包中的任何类型。

We could also match any type within the com.baeldung package or a sub-package.

@Pointcut("within(com.baeldung..*)")

3.3 this 和 target

this 将匹配限制为 bean 引用是给定类型的实例的连接点,而 target 将匹配限制为目标对象是给定类型的实例的连接点。前者在 Spring AOP 创建基于 CGLIB 的代理时工作,后者在创建基于 JDK 的代理时使用。假设目标类实现了一个接口:

this limits matching to join points where the bean reference is an instance of the given type, while target limits matching to join points where the target object is an instance of the given type. The former works when Spring AOP creates a CGLIB-based proxy, and the latter is used when a JDK-based proxy is created. Suppose that the target class implements an interface:

public class FooDao implements BarDao {
    // ...
}

在这个案例里,Spring AOP 将使用基于 JDK 的代理,您应该使用 target 切点指示符,因为代理对象将是 Proxy 类的实例并实现 BarDao 接口:

In this case, Spring AOP will use the JDK-based proxy and you should use the target PCD because the proxied object will be an instance of Proxy class and implement the BarDao interface:

@Pointcut("target(com.baeldung.pointcutadvice.dao.BarDao)")

反过来说,如果 FooDao 未实现任何接口或 proxyTargetClass 属性设置为 true,则代理对象将是 FooDao 的子类,并且可以使用 this 切点指示符:

On the other hand if FooDao doesn’t implement any interface or proxyTargetClass property is set to true then the proxied object will be a subclass of FooDao and the this PCD could be used:

@Pointcut("this(com.baeldung.pointcutadvice.dao.FooDao)")

3.4 args

这个切点指示符用于匹配特定的方法参数:

This PCD is used for matching particular method arguments:

@Pointcut("execution(* *..find*(Long))")

这个切点匹配任何以 find 开头并且只有一个 Long 类型参数的方法。如果我们想匹配具有任意数量参数但第一个参数为 Long 类型的方法,我们可以使用以下表达式:

This pointcut matches any method that starts with find and has only one parameter of type Long. If we want to match a method with any number of parameters but having the fist parameter of type Long, we could use the following expression:

@Pointcut("execution(* *..find*(Long,..))")

3.5 @target

这个 @target 切点指示符(不要与上述 target 指示符 混淆)将匹配限制为执行对象的类具有给定类型注释的连接点:

The @target PCD (not to be confused with the target PCD described above) limits matching to join points where the class of the executing object has an annotation of the given type:

@Pointcut("@target(org.springframework.stereotype.Repository)")

3.6 @args

此 切点指示符 将匹配限制为连接点,其中传递的实际参数的运行时类型具有给定类型的注解。假设我们要跟踪所有接受用 @Entity 注解的 bean 的方法:

This PCD limits matching to join points where the runtime type of the actual arguments passed have annotations of the given type(s). Suppose that we want to trace all the methods accepting beans annotated with @Entity annotation:

@Pointcut("@args(com.baeldung.pointcutadvice.annotations.Entity)")
public void methodsAcceptingEntities() {}

要访问参数,我们应该为 通知 提供一个 连接点 参数:

To access the argument we should provide a JoinPoint argument to the advice:

@Before("methodsAcceptingEntities()")
public void logMethodAcceptionEntityAnnotatedBean(JoinPoint jp) {
    logger.info("Accepting beans with @Entity annotation: " + jp.getArgs()[0]);
}

3.7 @within

此 切点指示符 将匹配限制为具有给定注解的类型中的连接点:

This PCD limits matching to join points within types that have the given annotation:

@Pointcut("@within(org.springframework.stereotype.Repository)")

这相当于:

Which is equivalent to:

@Pointcut("within(@org.springframework.stereotype.Repository *)")

3.8 @annotation

此 切点指示符 将匹配限制为连接点的主题具有给定注解的连接点。例如,我们可以创建一个 @Loggable 注解:

This PCD limits matching to join points where the subject of the join point has the given annotation. For example we may create a @Loggable annotation:

@Pointcut("@annotation(com.baeldung.pointcutadvice.annotations.Loggable)")
public void loggableMethods() {}

然后我们可以记录由该注解标记的方法的执行:

Then we may log execution of the methods marked by that annotation:

@Before("loggableMethods()")
public void logMethod(JoinPoint jp) {
    String methodName = jp.getSignature().getName();
    logger.info("Executing method: " + methodName);
}

4. 结合切点表达式

切入点表达式可以使用 &&|| 操作符进行组合:

Pointcut expressions can be combined using &&, || and ! operators:

@Pointcut("@target(org.springframework.stereotype.Repository)")
public void repositoryMethods() {}

@Pointcut("execution(* *..create*(Long,..))")
public void firstLongParamMethods() {}

@Pointcut("repositoryMethods() && firstLongParamMethods()")
public void entityCreationMethods() {}

5. 总结

Spring AOP切点 的 快速介绍中,我们展示了一些切点表达式的使用示例。

In this quick intro to Spring AOP and pointcuts, we illustrated some examples of pointcut expressions usage.

(本篇)完整的示例集 可以在 GitHub 上找到。

The full set of examples can be found over on GitHub.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring 中的切点表达式介绍 的相关文章

随机推荐

  • 【雅思备考】写作表达积累

    小作文 Line graph amount of source of provided generating 用来描述来源 means of xxx generation 生产方式 over a period of over the per
  • 【重磅推荐】vue之web3.js以太坊开发总结与完整案例!

    一个完整的Vue web3 js 基于Metamask开发测试和正式上线 FirstContract sol文件 pragma solidity gt 0 4 24 lt 0 7 0 contract FirstContract strin
  • www外部异步加载(不卡)-适合大量加载

    www外部异步加载 不卡 适合大量加载
  • 第一二天作业-BGP MPLS + OSPF分流互备做法

    三 MPLS OSPF分流互备做法 MPLS OSPF分流互备做法配置命令 在中间骨干区域所有路由器先配置OSPF 然后在中间骨干区域所有路由器上配置MPLS 先创建mpls lsr id 在全局开启mpls 在全局开启mpls ldp 在
  • Linux操作系统的层次与组成

    1 Linux操作系统的层次结构 简单来说 Linux操作系统整体分为三层 1 硬件系统 包括CPU 内存 硬盘 网卡等 2 内核 这是操作系统的核心 负责管理硬件系统 同时为上层的应用程序提供操作接口 3 用户进程 表示计算机中运行的所有
  • java版微信和支付宝 支付的调起 和 回调

    写下项目中经常用到的微信和支付宝支付的拉起和回调的代码 1 支付参数和退款参数的封装 package co yixiang modules storePaymentOrder payment dto import lombok Data 支
  • tensorflow训练的模型,用C++ 部署,需要的看过来

    目录 1 先准备tensorflow 和 opencv 的lib 2 项目配置就不说了 3 试一下效果 4 代码 首先 感谢一下rockingdingo Issues rockingdingo tensorflow tutorial Git
  • 入行IT,为什么建议你学Java?

    计算机编程语言 顾名思义 是人用来跟计算机交流的编程语言 学好一门热门的计算机编程语言进入IT行业 获得较高的薪资是没有问题的 关键是热门的计算机编程语言超级多 计算机编程语言入门学什么好 当然是Java 想必很多朋友也很好奇 如此多的计算
  • 【Web方向】 PHP代码审计 CTF题目wp1

    目录 一 第一步 二 第二步 三 第三步 四 第四步 README 一 第一步 分析这道题 是要求使判断条件符合 然后输出flag 第一个if语句是不能直接给data赋值Welcome to CTF的 否则会这样无反应 查了下才知道这是因为
  • 四十一.枚举问题2.生理周期

    生理周期 解题思路 从d 1天开始 一直试到第21252天 对其中每个日期k 看是否满足 k p 23 0 k e 28 0 k i 33 0 include
  • 全自动高清录播服务器,全自动高清录播服务器 高清录播系统

    高清录播系统外观参数 规格参数是了解一台设备的基础 多家高清录播服务器对比之后发现虽有小异 却基本相同 那如何从外观参数上决出移动录播主机的是否高能呢 从外观看常规移动录播主机大小与功能成正比 其次 常规的移动录播主机虽配有高频 CPU 功
  • (Ext基础篇) 弹出窗口

    从外观上来讲 浏览器自带的alert confirm prompt等对话框并不好看 而且配置也不灵活 诸如按钮的添加 删除 以及修改按下按钮所触发的事件等操作都非常难以执行 而在EXT的msgbox里都能实现 而且外观相当漂亮 本节将详细介
  • Idea内存占用过高解决方法

    问题描述 大多数人都知道使用idea时 发现idea内存消耗比较严重 尤其开启了idea后 CPU占比可以直接飙升到100 这主要体现在刚启动的时候 系统的内存高达80 以上 甚至风扇呼呼作响 于是开始找各种解决方案 目前 就我个人电脑来说
  • Ruby on Rails微信开发1——开发模式的启用与接口配置

    参照博客 027 微信公众帐号开发教程第3篇 开发模式启用及接口配置 根据微信开发者文档 启用公共平台开发者模式并进行接口配置流程如下 加密 校验流程如下 1 将token timestamp nonce三个参数进行字典序排序 2 将三个参
  • Spark SQL 之 Temporary View

    Spark SQL 之 Temporary View spark SQL的 temporary view 是支持原生SQL 的方式之一 spark SQL的 DataFrame 和 DataSet 均可以通过注册 temporary vie
  • 华为OD机试真题-跳房子II-2023年OD统一考试(B卷)

    题目描述 跳房子 也叫跳飞机 是一种世界性的儿童游戏 游戏参与者需要分多个回合按顺序跳到第1格直到房子的最后一格 跳房子的过程中 可以向前跳 也可以向后跳 假设房子的总格数是count 小红每回合可能连续跳的步数都放在数组steps中 请问
  • 《三》微软Dynamics CRM 2016单服务器安装部署(Dynamics CRM 2016 安装)

    Microsoft Dynamic CRM 2016安装 在 AD域控和数据库服务器安装好的前提下 接下来我们来安装 Dynamic CRM Server 一 以具有管理员级别特权的用户身份登录到将安装Microsoft Dynamics
  • 如何使用Log4j?

    1 Log4j是什么 Log4j可以帮助调试 有时候debug是发挥不了作 用的 和分析 要下载和了解更详细的内容 还是访问其官方网站吧 http jakarta apache org log4j 2 Log4j的概念 Log4j中有三个主
  • Springboot Maven或Gradle 解决log4j2漏洞

    log4j2漏洞风靡全球 影响的版本范围 Apache Log4j 2 x lt 2 14 1 根据官方的解释需要将log4j2包的版本 升级到2 15 0 测试使用 Springboot 2 1 5 Gradle 6 3版本进行测试 当时
  • Spring 中的切点表达式介绍

    Spring 中的切点表达式介绍 翻译原文链接 Introduction to Pointcut Expressions in Spring 1 概述 在本教程中 我们将讨论 Spring AOP 切点表达式语言 In this tutor