AOP 概念

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

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

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

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

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

  • 引入(Introduction):代表类型声明附加方法或字段。Spring AOP 允许您向任何被通知的对象引入新的接口(以及相应的实现)。例如,您可以使用引入来使 bean 实现 IsModified 接口,以简化缓存。(引入在 AspectJ 社区中被称为跨类型声明(inter-type declaration)。)

  • 目标对象(Target object):被一个或多个切面通知的对象。也称为“被通知对象(advised object)”。由于 Spring AOP 是通过运行时代理实现的,因此此对象始终是一个代理对象。

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

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

Spring AOP 包括以下类型的通知

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

  • 返回后通知(After returning advice):在连接点正常完成(例如,如果方法返回而未抛出异常)后运行的通知。

  • 抛出后通知(After throwing advice):如果方法因抛出异常而退出,则运行的通知。

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

  • 环绕通知(Around advice):环绕连接点(例如方法调用)的通知。这是最强大的通知类型。环绕通知可以在方法调用之前和之后执行自定义行为。它还负责选择是继续执行连接点,还是通过返回自己的返回值或抛出异常来中止被通知方法的执行。

环绕通知是最通用的通知类型。由于 Spring AOP,像 AspectJ 一样,提供了全系列的通知类型,我们建议您使用能够实现所需行为的最不强大的通知类型。例如,如果您只需要使用方法的返回值更新缓存,那么最好实现返回后通知而不是环绕通知,尽管环绕通知可以实现相同的功能。使用最具体的通知类型可以提供更简单的编程模型,并减少出错的可能性。例如,您不需要在用于环绕通知的 JoinPoint 上调用 proceed() 方法,因此也就不会忘记调用它。

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

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

© . This site is unofficial and not affiliated with VMware.