面试对线记录13 AOP
AOP这个东西我在和面试官对线的时候经常遇到,AOP又叫做面向切面编程,这个机制存在的目的就是为了解耦,AOP可以让一组类共享相同的行为,在OOP也就是面向对象编程中只能继承和实现接口,而且众所周知,在Java类中的继承只能单继承,不能多继承,故就用到了AOP这个机制。
再通俗一点就是说提供一个为一个业务实现提供切面注入的机制,通过这种方式,在业务运行中将定义好的切面通过切入点绑定到业务当中,目的是为了把一些特殊的逻辑绑定到业务中,比如在项目中记录日志的一个需求,通俗来说就是一个很简单的save操作,我们在写代码的时候一遍又一遍的重写和调用,这肯定会增加代码的耦合度,而且这样子更显的我们是码农。。。
接下来介绍一些aop的专有名词:
- 通知
需要完成的工作叫做通知,就是你写的业务逻辑中需要的比如事务和日志等提前定义好,然后再在需要的地方用起来。 - 切点
就是在类中筛选出一些方法来作为切点,形象的来说上面说的通知是定义了切面的动作或者执行动机的话,那么切点就是定义了执行的地点 - 切面
就是上面的通知和切点的结合,通知和切点共同定义了切面的全部内容,它是干什么的,什么时候在哪里执行。 - 引入 就是在不改变一个现有类的情况下,为该类添加属性和方法,可以在无需修改现有累的前提下,让他们具有新的行为和状态,就是吧上面说的切面用到目标类中去。
- 织入
把切面加入到程序代码中,切面在指定的连接点被织入到目标对象中,在目标对象的生命周期中有很多个点可以进行织入,比如编译期,类加载期,运行期等等 - 目标对象
被一个或者多个切面所通知的对象,Spring AOP是通过运行时代理实现的,这个对对象永远是一个被代理的对象。
举个例子就是
public class UserService{
void save(){}
List list(){}
}
如果我们想实现一个需求,就是在上面的save方法之前开启事务,在方法后关闭事务,在抛出异常时回滚事务,那么,在UserService中的所有方法都是连接点(JoinPoint),save()方法就是切点(Poincut),按照需求说的,我们在save()方法前后执行的方法就是通知(Advice),切点和通知合起来就是一个切面(Aspect).save()方法就是目标(target)。把想要执行的代码动态的加入到save()方法前后就是织入(Weaving).可能在工作中,有些大佬会把通知称为增强,其实想来也是对的,因为我们在我们需要操作的业务方法周围加上其他方法,这说白了就是对这个方法的增强。
接下来记录一下AOP的通知类型
- before(前置通知):在方法开始执行前执行
- after(后置通知):在方法执行后执行
- afterReturning(返回后通知):在方法返回后执行
- afterThrowing(异常通知):在抛出异常时执行
- around(环绕通知):在方法执行前和执行后都会执行
这五个通知的执行顺序就是 around > before > around > after > afterReturning