Spring AOP Capability and goals

5.1。AOP概念

让我们首先定义一些中心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 Framework中,AOP代理是JDK动态代理或CGLIB代理。

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

Spring AOP包括以下类型的建议:

  • 建议之前:在连接点之前运行但无法阻止执行流程进入连接点的建议(除非它抛出异常)。

  • 返回建议后:在连接点正常完成后运行的建议(例如,如果方法返回而不抛出异常)。

  • 抛出建议后:如果方法通过抛出异常退出,则执行建议。

  • 在(最终)建议之后:无论连接点退出的方式(正常或异常返回),都要执行建议。

  • 围绕建议:围绕连接点的建议,例如方法调用。这是最有力的建议。around通知可以在方法调用之前和之后执行自定义行为。它还负责选择是继续加入点还是通过返回自己的返回值或抛出异常来快速建议的方法执行。

围绕建议是最普遍的建议。由于Spring AOP(如AspectJ)提供了全方位的建议类型,因此我们建议您使用可以实现所需行为的最不强大的建议类型。例如,如果您只需要使用方法的返回值更新缓存,那么最好实现返回后的建议而不是周围的建议,尽管周围的建议可以完成同样的事情。使用最具体的建议类型可以提供更简单的编程模型,减少错误的可能性。例如,您不需要proceed() 在JoinPointused for around advice 调用该方法,因此,您无法调用它。

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

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

5.2。Spring AOP功能和目标

Spring AOP是用纯Java实现的。不需要特殊的编译过程。Spring AOP不需要控制类加载器层次结构,因此适合在servlet容器或应用程序服务器中使用。

Spring AOP目前仅支持方法执行连接点(建议在Spring bean上执行方法)。虽然可以在不破坏核心Spring AOP API的情况下添加对字段拦截的支持,但未实现字段拦截。如果您需要建议字段访问和更新连接点,请考虑使用AspectJ等语言。

Spring AOP的AOP方法与大多数其他AOP框架的方法不同。目的不是提供最完整的AOP实现(尽管Spring AOP非常强大)。相反,目标是在AOP实现和Spring IoC之间提供紧密集成,以帮助解决企业应用程序中的常见问题。

因此,例如,Spring Framework的AOP功能通常与Spring IoC容器一起使用。通过使用普通bean定义语法来配置方面(尽管这允许强大的“自动代理”功能)。这是与其他AOP实现的重要区别。使用Spring AOP无法轻松或高效地完成某些操作,例如建议非常细粒度的对象(通常是域对象)。在这种情况下,AspectJ是最佳选择。但是,我们的经验是Spring AOP为适合AOP的企业Java应用程序中的大多数问题提供了出色的解决方案。

Spring AOP从未努力与AspectJ竞争,以提供全面的AOP解决方案。我们认为,基于代理的框架(如Spring AOP)和完整的框架(如AspectJ)都很有价值,而且它们是互补的,而不是竞争。Spring将Spring AOP和IoC与AspectJ无缝集成,以在一致的基于Spring的应用程序架构中实现AOP的所有使用。此集成不会影响Spring AOP API或AOP Alliance API。Spring AOP仍然向后兼容。有关 Spring AOP API的讨论,请参阅以下章节

 

Spring框架的核心原则之一是非侵入性。这个想法是,您不应该被迫在您的业务或域模型中引入特定于框架的类和接口。但是,在某些地方,Spring Framework确实为您提供了将Spring Framework特定的依赖项引入代码库的选项。为您提供此类选项的基本原理是,在某些情况下,以这种方式阅读或编写某些特定功能可能更容易。但是,Spring Framework(几乎)总是为您提供选择:您可以自由决定哪种选项最适合您的特定用例或场景。

与本章相关的一个选择是选择哪种AOP框架(以及哪种AOP样式)。您可以选择AspectJ,Spring AOP或两者。您还可以选择@AspectJ注释样式方法或Spring XML配置样式方法。本章选择首先介绍@ AspectJ风格的方法,这一事实不应被视为Spring团队倾向于采用Spring XML配置风格的@AspectJ注释风格方法。

请参阅选择要使用的AOP声明样式,以更全面地讨论每种样式的“为什么和为何”。

5.3。AOP代理

Spring AOP默认使用AOP代理的标准JDK动态代理。这使得任何接口(或接口集)都可以被代理。

Spring AOP也可以使用CGLIB代理。这是代理类而不是接口所必需的。默认情况下,如果业务对象未实现接口,则使用CGLIB。由于优化的做法是编程接口而不是类,业务类通常实现一个或多个业务接口。可以 强制使用CGLIB,在那些需要建议未在接口上声明的方法或需要将代理对象作为具体类型传递给方法的情况下(希望很少见)。

掌握Spring AOP是基于代理的这一事实非常重要。请参阅 了解AOP代理,以全面了解此实现细节的实际含义。

5.4。@AspectJ支持

@AspectJ指的是将方面声明为使用注释注释的常规Java类的样式。作为AspectJ 5版本的一部分,AspectJ项目引入了@AspectJ样式 Spring使用AspectJ提供的库解释与AspectJ 5相同的注释,用于切入点解析和匹配。但是,AOP运行时仍然是纯Spring AOP,并且不依赖于AspectJ编译器或weaver。

posted @ 2019-04-19 15:34  TomFord  阅读(149)  评论(0编辑  收藏  举报