AOP 概念
让我们首先定义一些中心 AOP 概念和术语。这些术语不是特定于 Spring 的。不幸的是,AOP 术语并不特别直观。但是,如果 Spring 使用自己的术语,那将会更加混乱。
-
方面:跨越多个类的关注点的模块化。事务管理是企业 Java 应用程序中跨领域关注的一个很好的例子。在 Spring AOP 中,方面是通过使用常规类(基于架构的方法)或使用
@Aspect
注解的常规类(@AspectJ 风格)来实现的。 -
连接点:程序执行期间的一个点,例如方法的执行或异常的处理。在 Spring AOP 中,连接点始终表示方法执行。
-
建议:方面在特定连接点采取的操作。不同的建议类型包括“around”、“before”和“after”建议。(稍后将讨论建议类型。)许多 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 的关键,这区别于仅提供拦截的旧技术。切点使建议能够独立于面向对象层次结构进行定位。例如,您可以将提供声明式事务管理的环绕建议应用于跨越多个对象的多个方法集(例如服务层中的所有业务操作)。