Spring AOP理解
1、概念(Aspect Oriented Programming:面向切面编程)
什么时候会出现面向切面编程的需求?按照软件重构的思想,如果多个类中出现重复的代码,就应该考虑定义一个共同的抽象类,将这些共同的代码提取到抽象类中,比如Teacher,Student都有username,那么就可以把username及相关的get、set方法抽取到SysUser中,这种情况,我们称为纵向抽取。
但是如果,我们的情况是以下情况,又该怎么办? 给所有的类方法添加性能检测,事务控制,该怎么抽取? PerformanceMonitor TransactionManager AOP就是希望将这些分散在各个业务逻辑代码中的相同代码,通过横向切割的方式抽取到一个独立的模块中,让业务逻辑类依然保存最初的单纯。
简单的说就是提取代码中重复的代码,在需要执行的时候,采用动态代理的方式对已有方法进行通知(增强)。所以作用可以归结为减少重复代码、提高开发效率、维护方便
注:1,AOP编程不是Spring独有的,Spring只是支持AOP编程的框架之一,这一点非常重要,切勿搞反了关系。2,AOP分两类,一类可以对方法的参数进行拦截,一类是对方法进行拦截,SpringAOP属于后者,所以Spring的AOP是属于方法级的
2、AOP的相关术语
(1)Joinpoint(连接点)
所谓连接点是指那些被拦截到的点。在 spring 中,这些点指的是方法,因为 spring 只支持方法类型的 连接点。
(2)Pointcut(切入点)
所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义.
(3)Advice(通知/增强)
所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。
通知的类型:前置通知, 后置通知, 异常通知, 最终通知, 环绕通知。
(4)Advice(通知/增强)
所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。
通知的类型:
前置通知**(before)**:在执行业务代码前做些操作,比如获取连接对象
后置通知**(afterReturning)**,在执行业务代码后无异常,会执行的操作
异常通知**(afterThrowing)**:在执行业务代码后出现异常,需要做的操作,比如回滚事务
最终通知**(after)**:在执行业务代码后做些操作,无论是否发生异常,它都会执行,比如关闭连接对象.
环绕通知:(around)
(5)Target(目标对象)
代理的目标对象。
(6)Weaving(织入)
是指把增强应用到目标对象来创建新的代理对象的过程,或者说,就是生成代理对象并将切面 内容融入到业务流程的过程。
spring 采用动态代理织入,而 AspectJ 采用编译期织入和类装载期织入。
(7)Proxy(代理)
一个类被AOP织入增强后,就产生了一个代理类。
(8)切面(Aspect)
切面由切点和增强组成,它既包括了横切逻辑的定义,也包括了连接点的定义,SpringAOP就是将切面所定义的横切逻辑织入到切面所制定的连接点中。SpringAOP将切面定义的内容织入到我们的代码中,从而实现前后的控制逻辑。 比如我们常写的拦截器Interceptor,这就是一个切面类.
3、示例实现
导入AOP依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
(1)通知类定义:
package com.example.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
i