文章目录
一、AOP常用术语
(术语中部分内容参考自《Spring实战》(第四版)
连接点(Joinpoint)
简述:
所有可以定义切点的“地方”
,或者说是所有可以去添加增强代码的“地方”。
详述:是在应用程序执行过程中能够插入切面的一个点,这个点可以是调用方法时,抛出异常时,甚至修改一个字段时,切面代码可以利用这些点插入到应用程序的正常流程中,并增加新的行为。
切点(Pointcut)
需要去添加代码的“地方”。
描述了切面织入的位置。 切点的定义会匹配通知所要织入的一个或多个连接点,可以指定明确的类和方法,也可以使用正则表达式匹配符合条件的类和方法来指定这些切点。
通知(Advice)
向切点处动态添加的那部分代码。
描述了切面要做的工作。
切面(Aspect)
切点+通知。
引入(Introduction)
向现有类添加新方法或属性。
织入(Weaving)
把切面应用到目标对象并创建新的代理对象的过程。
切面在指定的连接点被织入到目标对象中,在目标对象的生命周期里有多个点可以进入织入:
- 编译期:切面在目标类编译时被织入。
- 类加载期:切面在目标类加载到JVM时被织入。
- 运行期:切面在应用运行的某个时期被织入,通常在织入切面时,AOP容器会为目标对象动态创建一个代理对象,Spring AOP就是以这种方式织入切面的。
二、解析五种通知类型
【前言】
此部分内容所在类的声明:
首先定义切点
,如下(仅为一个例子),
切点的定位借助了规则
,第一个*为方法任意返回值,第二个*为此包中的任意类,第三个*为类中任意方法,最后两个…为方法参数类型和个数任意。
【当然,也可以使用自定义注解的方式,不过由于注解编写后需加入到所要增强的方法处,因此是侵入式的,并不提倡,(不过就近期来看,Spring系列仍是并将长期是主流,因此侵入式的写法也不会有太大问题,不过长远来看,确实是非侵入式方案更稳妥一些)】。
此后我们便可以用pointcut()来应用于通知注解中,从而为通知赋予切点,二者整体又组成了切面。
前置通知
@Before前置通知:
在目标方法被调用之前调用此通知。
后置通知
@After后置通知:
在目标方法完成后调用此通知,提前于返回通知。
返回通知
@AfterReturning返回通知
:在目标方法执行执行之后调用此通知。晚于后置通知,注解中的returning属性值表示目标方法返回值的变量名,并且此返回值类型要与其对应否则无法拦截到返回信息,如果需要拦截所有返回类型的目标方法(包括void),则此通知中的对应返回值类型应为Object。
异常通知
@AfterThrowing异常通知
:在目标方法抛出异常时调用此通知。注解中throwing属性值为目标方法抛出的异常对象名,其类型也可以是其异常对象的父类,若想拦截所有目标方法的异常,将其声明为Exception类型即可,特殊情况下声明为Throwable类型。
环绕通知
@Around环绕通知:
包含了被通知的方法,可以替代上面四种通知的功能实现,可谓是一个全能型通知。
此通知中方法的参数类型为ProceedingJoinPoint,有所区别于以上四种通知的JoinPoint类型。ProceedingJoinPoint类继承自JoinPoint类,在父类基础上增加proceed()方法,此方法用于让目标方法执行,有些类似于反射机制。
三、实例测试
最后测试一下算是收个尾。
1.项目结构
2.测试用的部分核心代码
(1)MyCalculatorImpl类:
(2)@EnableAspectJAutoProxy:用在配置类上,启动AspectJ自动代理。
(3)上述五种通知和切点都写在了下面这个类中(前四个通知和第五个通知只开启一个即可)。
(4)Main
3.运行结果
附:XML配置方式
附:Spring的API接口方式
Spring中还有一种实现AOP的方式,就是使用Spring的API接口实现