面向切面编程与 Spring
面向切面编程(AOP)通过提供另一种思考程序结构的方式来补充面向对象编程(OOP)。在 OOP 中,模块化的关键单元是类,而在 AOP 中,模块化的单元是切面。切面使得能够对跨多个类型和对象的关注点(例如事务管理)进行模块化。(在 AOP 文献中,这些关注点通常被称为“横切”关注点。)
Spring 的一个关键组件是 AOP 框架。虽然 Spring IoC 容器并不依赖于 AOP(这意味着如果你不想使用 AOP,你可以不使用它),但 AOP 补充了 Spring IoC,以提供一个非常强大的中间件解决方案。
AOP 在 Spring 框架中用于:
-
提供声明式企业服务。最重要的服务是 声明式事务管理。
-
让用户实现自定义切面,补充他们对面向对象编程(OOP)的使用与面向切面编程(AOP)。
如果您只对通用声明式服务或其他预打包的声明式中间件服务(例如连接池)感兴趣,您无需直接使用 Spring AOP,可以跳过本章的大部分内容。
章节摘要
📄️ AOP 概念
让我们开始定义一些核心的 AOP 概念和术语。这些术语并不是特定于 Spring 的。不幸的是,AOP 术语并不是特别直观。然而,如果 Spring 使用自己的术语,那将更加令人困惑。
📄️ Spring AOP 的能力和目标
Spring AOP 是用纯 Java 实现的。无需特殊的编译过程。Spring AOP 不需要控制类加载器层次,因此适合在 servlet 容器或应用服务器中使用。
📄️ AOP 代理
Spring AOP 默认使用标准 JDK 动态代理来创建 AOP 代理。这使得任何接口(或一组接口)都可以被代理。
🗃️ @AspectJ 支持
7 个项目
📄️ 基于模式的 AOP 支持
如果您更喜欢基于 XML 的格式,Spring 还提供了使用 aop 命名空间标签定义切面的支持。与使用 @AspectJ 风格时相同的切入点表达式和通知类型都得到了支持。因此,在本节中,我们将重点关注该语法,并将读者引导到上一节的讨论(@AspectJ 支持),以理解如何编写切入点表达式和通知参数的绑定。
📄️ 选择使用哪种 AOP 声明风格
一旦你决定某个方面是实现特定需求的最佳方法,你如何在使用 Spring AOP 或 AspectJ 之间进行选择,以及在 Aspect 语言(代码)风格、@AspectJ 注解风格或 Spring XML 风格之间进行选择?这些决策受到多个因素的影响,包括应用程序需求、开发工具以及团队对 AOP 的熟悉程度。
📄️ 混合方面类型
完全可以通过使用自动代理支持、模式定义的 aop:aspect 切面、声明的 aop:advisor 顾问,甚至在同一配置中使用其他风格的代理和拦截器来混合 @AspectJ 风格的切面。所有这些都是通过使用相同的底层支持机制实现的,并且可以毫无困难地共存。
📄️ 代理机制
Spring AOP 使用 JDK 动态代理或 CGLIB 来为给定的目标对象创建代理。JDK 动态代理是内置于 JDK 中的,而 CGLIB 是一个常见的开源类定义库(重新打包到 spring-core 中)。
📄️ 程序化创建 @AspectJ 代理
除了通过使用 aop:config 或 aop:aspectj-autoproxy 在配置中声明切面外,还可以通过编程方式创建代理来建议目标对象。有关 Spring 的 AOP API 的完整细节,请参见下一章。在这里,我们想要重点关注使用 @AspectJ 切面自动创建代理的能力。
📄️ 在 Spring 应用程序中使用 AspectJ
到目前为止,我们在本章中讨论的内容都是纯 Spring AOP。在本节中,我们将探讨如何使用 AspectJ 编译器或织入器,而不是仅仅依赖于 Spring AOP,或者在 Spring AOP 的基础上进行扩展,以满足更复杂的需求。
📄️ 进一步资源
有关 AspectJ 的更多信息可以在 AspectJ 网站上找到。