上一篇我们围绕了AOP中代理模式的使用,这篇我们将主要围绕AOP的相关术语介绍,以及重点围绕基于注解的AOP进行相关知识的概述和使用说明。
AOP的相关术语
- 切面(Aspect):切面是一个模块化的横切关注点,它包含了一组通知和切点。通常,切面用于定义横切关注点的行为,如日志记录、事务管理等。
- 通知(Advice):通知是切面在特定切点上执行的动作。在 Spring AOP 中,有以下几种类型的通知:
- 前置通知(Before Advice):在目标方法执行之前执行。
- 后置通知(After Advice):在目标方法执行之后执行,无论目标方法是否抛出异常。
- 返回通知(After Returning Advice):在目标方法成功执行并返回结果后执行。
- 异常通知(After Throwing Advice):在目标方法抛出异常后执行。
- 环绕通知(Around Advice):在目标方法执行前后都执行,并可以控制目标方法的执行。
- 切点(Pointcut):切点是指在应用程序中选择连接点的表达式。它定义了哪些方法或类应该被通知所影响。切点使用表达式语言来匹配连接点。
- 连接点(Join Point):连接点是在应用程序执行过程中可以插入切面的点。它可以是方法调用、方法执行、异常抛出等。
- 引入(Introduction):引入允许向现有的类添加新的方法或属性。它允许在不修改现有类的情况下,向类添加新的功能。
- 目标对象(Target Object):目标对象是被通知的对象,它包含了切面所要应用的方法。
- 代理(Proxy):代理是一个对象,它包装了目标对象,并拦截对目标对象的访问。代理可以在目标对象的方法执行前后添加额外的逻辑。
- 织入(Weaving):织入是将切面应用到目标对象并创建新的代理对象的过程。织入可以在编译时、类加载时或运行时进行。(可以称之为横切关注点)
这些术语的作用:
- 提供统一的概念和术语:术语提供了一套统一的概念和术语,使开发人员能够更好地理解和沟通。通过使用共同的术语,可以减少误解和混淆,提高团队协作效率。
- 定义和描述 AOP 的各个组成部分:术语用于定义和描述 AOP 的各个组成部分,如切面、通知、切点等。它们提供了一种标准的方式来描述和理解 AOP 的概念和实现。
- 指导开发人员理解和使用 Spring AOP 框架:术语帮助开发人员理解和使用 Spring AOP 框架。通过熟悉和理解这些术语,开发人员可以更好地使用 Spring AOP 提供的功能和特性,实现横切关注点的处理。
- 促进知识共享和学习:术语作为一种共享的语言,促进了知识的共享和学习。开发人员可以通过使用相同的术语来交流和分享经验,从而加深对 Spring AOP 的理解和应用。
基于注解的AOP
基于注解的 AOP 是一种使用注解来定义切面和通知的方式。在传统的基于 XML 配置的 AOP 中,切面和通知的定义通常是通过 XML 配置文件来完成的,而基于注解的 AOP 则使用注解来实现这些定义,使得配置更加简洁和直观。
- 动态代理(InvocationHandler):JDK原生的实现方式,需要被代理的目标类必须实现接口。因为这个技术要求代理对象和目标对象实现同样的接口(兄弟两个拜把子模式)。
- cglib:通过继承被代理的目标类(认干爹模式)实现代理,所以不需要目标类实现接口。
- AspectJ:本质上是静态代理,将代理逻辑“织入”被代理的目标类编译得到的字节码文件,所以最终效果是动态的。weaver就是织入器。Spring只是借用了AspectJ中的注解。
常见的注解:
-
@Aspect
:用于定义切面类,标识该类为切面。 -
@Before
:用于定义前置通知,在目标方法执行之前执行。 -
@After
:用于定义后置通知,在目标方法执行之后执行,无论目标方法是否抛出异常。 -
@AfterReturning
:用于定义返回通知,在目标方法成功执行并返回结果后执行。 -
@AfterThrowing
:用于定义异常通知,在目标方法抛出异常后执行。 -
@Around
:用于定义环绕通知,在目标方法执行前后都执行,并可以控制目标方法的执行。
案例
导入相关依赖
创建接口实现注解横切
在Spring 配置文件中添加下述代码
测试类:
运行结果:
补充说明AOP中的切面优先级
相同目标方法上同时存在多个切面时,切面的优先级控制切面的内外嵌套顺序。
- 优先级高的切面:外面
- 优先级低的切面:里面
在基于注解的 AOP 中,切面的优先级可以通过以下方式进行控制:
- @Order 注解:可以在切面类上使用 @Order 注解来指定切面的优先级。@Order 注解的值越小,优先级越高。如果多个切面都使用了 @Order 注解,则优先级较高的切面将先于优先级较低的切面执行。
- 实现 Ordered 接口:可以让切面类实现 Ordered 接口,并实现其中的 getOrder() 方法来指定切面的优先级。getOrder() 方法返回的值越小,优先级越高。
- @Order 和 Ordered 接口的组合使用:可以同时使用 @Order 注解和实现 Ordered 接口的方式来控制切面的优先级。当切面类既使用了 @Order 注解,又实现了 Ordered 接口时,@Order 注解的优先级高于 Ordered 接口的 getOrder() 方法返回值。
需要注意的是,切面的优先级仅在多个切面同时应用于同一个连接点时才会起作用。如果切面应用于不同的连接点,优先级的设置将不会生效。
了解基于XML的AOP操作
在基于 XML 的 Spring AOP 中,切面和通知的定义通常是通过 XML 配置文件来完成的。以下是基于 XML 的 Spring AOP 的配置步骤:
- 定义切面类:创建一个切面类,其中包含了切面的逻辑和通知的定义。
- 创建 XML 配置文件:创建一个 XML 配置文件,用于定义切面和通知的关系。
- 配置切面和通知:在 XML 配置文件中,使用
<aop:config>
元素来配置切面和通知。 - 定义切点:使用
<aop:pointcut>
元素来定义切点,切点用于匹配连接点。 - 配置通知:使用
<aop:advisor>
元素来配置通知,将切面和切点关联起来。 - 引入其他配置:根据需要,可以在 XML 配置文件中引入其他的配置,如引入目标对象、引入代理等。
基于XML的AOP操作展示
XML文件配置
测试类
通过 aop:config 元素配置了切面和通知,使用 aop:pointcut 元素定义了切点,使用 aop:before、aop:after、aop:after-returning、aop:after-throwing、aop:around 元素配置了不同类型的通知。
通过基于 XML 的配置,可以灵活地定义和配置切面和通知,实现对目标对象的横切关注点的处理。