跳到主要内容

AOP 概念

ChatGPT-4o-mini 中英对照 AOP Concepts

让我们开始定义一些核心 AOP 概念和术语。这些术语并不是特定于 Spring 的。不幸的是,AOP 术语并不是特别直观。然而,如果 Spring 使用自己的术语,那将更加令人困惑。

  • 方面:对跨多个类的关注点进行模块化。事务管理是企业 Java 应用程序中一个很好的跨切关注点的例子。在 Spring AOP 中,方面可以通过使用常规类(基于模式的方法)或带有 @Aspect 注解的常规类(@AspectJ 风格)来实现。

  • 连接点:程序执行过程中的一个点,例如方法的执行或异常的处理。在 Spring AOP 中,连接点始终表示方法执行。

  • 通知:在特定连接点由方面采取的行动。不同类型的通知包括“环绕”、“前”和“后”通知。(通知类型将在后面讨论。)许多 AOP 框架,包括 Spring,将通知建模为拦截器,并在连接点周围维护一个拦截器链。

  • 切入点:匹配连接点的谓词。通知与切入点表达式相关联,并在切入点匹配的任何连接点上运行(例如,执行具有特定名称的方法)。连接点的概念与切入点表达式的匹配是 AOP 的核心,Spring 默认使用 AspectJ 切入点表达式语言。

  • 引入:代表某个类型声明额外的方法或字段。Spring AOP 允许您向任何被通知的对象引入新的接口(及其相应的实现)。例如,您可以使用引入使一个 bean 实现 IsModified 接口,以简化缓存。(在 AspectJ 社区中,引入被称为类型间声明。)

  • 目标对象:被一个或多个方面通知的对象。也称为“被通知对象”。由于 Spring AOP 是通过使用运行时代理实现的,因此该对象始终是一个代理对象。

  • AOP 代理:由 AOP 框架创建的对象,用于实现方面契约(通知方法执行等)。在 Spring 框架中,AOP 代理是 JDK 动态代理或 CGLIB 代理。

  • 编织:将方面与其他应用程序类型或对象链接以创建被通知对象。这可以在编译时(例如,使用 AspectJ 编译器)、加载时或运行时完成。Spring AOP 像其他纯 Java AOP 框架一样,在运行时执行编织。

Spring AOP 包括以下类型的通知:

  • 前置通知:在连接点之前运行的通知,但没有能力阻止执行流程继续到连接点(除非它抛出异常)。

  • 后置返回通知:在连接点正常完成后运行的通知(例如,如果一个方法在不抛出异常的情况下返回)。

  • 后置抛出通知:如果一个方法通过抛出异常退出,则运行的通知。

  • 后置(最终)通知:无论连接点以何种方式退出(正常或异常返回),都要运行的通知。

  • 环绕通知:包围连接点的通知,例如方法调用。这是最强大的通知类型。环绕通知可以在方法调用之前和之后执行自定义行为。它还负责选择是否继续到连接点,或者通过返回自己的返回值或抛出异常来快捷地结束被通知的方法执行。

环绕通知是最一般的通知类型。由于 Spring AOP 和 AspectJ 提供了全范围的通知类型,我们建议您使用能够实现所需行为的最弱通知类型。例如,如果您只需要使用方法的返回值更新缓存,您最好实现一个返回后通知,而不是环绕通知,尽管环绕通知也可以完成相同的事情。使用最具体的通知类型提供了一个更简单的编程模型,减少了出错的潜在可能性。例如,您不需要在用于环绕通知的 JoinPoint 上调用 proceed() 方法,因此,您不会遗漏调用它。

所有建议参数都是静态类型的,因此您可以使用适当类型的建议参数(例如,方法执行的返回值类型),而不是 Object 数组。

由切点匹配的连接点的概念是 AOP 的关键,这使其与仅提供拦截的旧技术区分开来。切点使得建议能够独立于面向对象的层次结构进行定位。例如,您可以将提供声明式事务管理的环绕建议应用于跨多个对象的一组方法(例如服务层中的所有业务操作)。