AOP 概念
让我们首先定义一些核心 AOP 概念和术语。这些术语不是 Infra 特有的。 不幸的是,AOP 术语并不是特别直观。 但是,如果 Infra 使用自己的术语,那将更加令人困惑。
-
Aspect(切面):跨越多个类的关注点的模块化。 事务管理是企业 Java 应用程序中横切关注点的一个很好的例子。 在 Infra AOP 中,切面是通过使用常规类(基于模式的方法)或使用
@Aspect注解的常规类(@AspectJ 风格)来实现的。 -
Join point(连接点):程序执行期间的一个点,例如方法的执行或异常的处理。 在 Infra AOP 中,连接点始终代表方法执行。
-
Advice(通知):切面在特定连接点采取的操作。 不同类型的 advice 包括“around”、“before”和“after” advice。(Advice 类型将在后面讨论。) 许多 AOP 框架(包括 Infra)将 advice 建模为拦截器,并在连接点周围维护拦截器链。
-
Pointcut(切入点):匹配连接点的谓词。 Advice 与切入点表达式关联,并在切入点匹配的任何连接点运行(例如,执行具有特定名称的方法)。 由切入点表达式匹配的连接点概念是 AOP 的核心,Infra 默认使用 AspectJ 切入点表达式语言。
-
Introduction(引介):代表类型声明额外的方法或字段。 Infra AOP 允许你向任何被通知对象引入新接口(以及相应的实现)。 例如,你可以使用引介使 bean 实现
IsModified接口,以简化缓存。 (在 AspectJ 社区中,引介被称为类型间声明。) -
Target object(目标对象):被一个或多个切面通知的对象。也称为“被通知对象”。 由于 Infra AOP 是使用运行时代理实现的,因此该对象始终是代理对象。
-
AOP proxy(AOP 代理):AOP 框架创建的对象,用于实现切面契约(advice 方法执行等)。 在 TODAY Framework 中,AOP 代理是 JDK 动态代理或 CGLIB 代理。
-
Weaving(织入):将切面与其他应用程序类型或对象链接以创建被通知对象。 这可以在编译时(例如,使用 AspectJ 编译器)、加载时或运行时完成。 Infra AOP 与其他纯 Java AOP 框架一样,在运行时执行织入。
Infra AOP 包括以下类型的 advice:
-
Before advice(前置通知):在连接点之前运行但无法阻止执行流继续到连接点的 advice(除非它抛出异常)。
-
After returning advice(返回后通知):在连接点正常完成后运行的 advice(例如,如果方法返回而没有抛出异常)。
-
After throwing advice(抛出后通知):如果方法通过抛出异常退出,则运行 advice。
-
After (finally) advice(最终通知):无论连接点以何种方式退出(正常或异常返回),都会运行 advice。
-
Around advice(环绕通知):围绕连接点(如方法调用)的 advice。 这是最强大的 advice 类型。环绕 advice 可以在方法调用之前和之后执行自定义行为。 它还负责选择是继续到连接点,还是通过返回自己的返回值或抛出异常来捷径被通知方法的执行。
环绕 advice 是最通用的 advice 类型。
由于 Infra AOP 与 AspectJ 一样,提供了全方位的 advice 类型,因此我们建议你使用能够实现所需行为的最不强大的 advice 类型。
例如,如果你只需要使用方法的返回值更新缓存,那么实现返回后 advice 比环绕 advice 更好,尽管环绕 advice 可以完成相同的事情。
使用最具体的 advice 类型提供了更简单的编程模型,并且出错的可能性更小。
例如,你不需要在用于环绕 advice 的 JoinPoint 上调用 proceed() 方法,因此,你不会因为忘记调用它而失败。
所有 advice 参数都是静态类型的,因此你可以使用适当类型的 advice 参数(例如,方法执行的返回值的类型),而不是 Object 数组。
由切入点匹配的连接点概念是 AOP 的关键,这将其与仅提供拦截的旧技术区分开来。 切入点使 advice 可以独立于面向对象的层次结构进行定位。 例如,你可以应用提供声明式事务管理的环绕 advice 到一组跨越多个对象的方法(例如服务层中的所有业务操作)。