使用Spring的面向切面编程
面向切面编程(AOP)通过提供另一种思考程序结构的方式,补充了面向对象编程(OOP)。在OOP中,模块化的基本单元是类,而在AOP中,模块化的基本单元是切面。切面使得能够对跨越多种类型和对象的关注点(如事务管理)进行模块化。(在AOP的文献中,这类关注点通常被称为“横向切面”关注点。)
Spring 的关键组成部分之一是 AOP 框架。虽然 Spring IoC 容器并不依赖于 AOP(这意味着如果你不想使用 AOP,也可以不使用它),但 AOP 与 Spring IoC 相辅相成,提供了非常强大的中间件解决方案。
在Spring框架中,AOP被用来:
-
提供声明式企业服务。其中最重要的服务是声明式事务管理。
-
允许用户实现自定义方面(custom aspects),通过面向切面编程(AOP)来补充他们的面向对象编程(OOP)使用。
如果您只对通用的声明式服务或其他预封装的声明式中间件服务(如池化)感兴趣,那么您无需直接使用Spring AOP,可以跳过本章的大部分内容。
部分摘要
📄️ AOP(面向切面编程)概念
让我们首先定义一些核心的AOP概念和术语。这些术语并不是Spring特有的。不幸的是,AOP的术语并不是特别直观易懂。然而,如果Spring使用它自己的术语,反而会更加令人困惑。
📄️ Spring AOP(面向切面编程)的功能与目标
Spring AOP是用纯Java实现的。它不需要特殊的编译过程。Spring AOP不需要控制类加载器的层次结构,因此适用于在servlet容器或应用服务器中使用。
📄️ AOP代理(AOP Proxies)
Spring AOP默认使用标准的JDK动态代理来实现AOP代理。这使得任何接口(或一组接口)都可以被代理。
🗃️ @AspectJ 支持
7 个项目
📄️ 基于模式的AOP支持
如果你更喜欢基于XML的格式,Spring也提供了使用aop命名空间标签来定义切面的支持。所支持的切点表达式(pointcut expressions)和通知类型(advise kinds)与使用@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 Proxies的程序化创建
除了使用aop:config或aop:aspectj-autoproxy在配置中声明切面外,还可以通过编程方式创建用于通知目标对象的代理。有关Spring AOP API的完整细节,请参阅下一章。在这里,我们想重点介绍如何使用@AspectJ切面来自动创建代理。
📄️ 在Spring应用程序中使用AspectJ
在本章中,我们迄今为止所讨论的内容都是纯粹的Spring AOP。在这一节中,我们将探讨当你的需求超出了Spring AOP本身所提供的功能时,如何使用AspectJ编译器或织入器来替代或补充Spring AOP。
📄️ 更多资源
有关AspectJ的更多信息,可以在AspectJ官方网站上找到。