AOP
1.AOP与OOP
-
OOP(Object Oriented Programming,面向对象编程)
-
AOP(Aspect Oriented Programming,面向切面编程)
-
POP(Process Oriented Programming,面向过程编程)
-
FP(Functional Programming,函数式编程)
AOP的诞生就是为了弥补OOP(面向对象编程)的不足。面向对象非常擅长 解决纵向的业务逻辑,但是对于横向的公共操作却显得有些“力不从心”。
2.用在什么地方
AOP中的核心概念:
-
Advice(通知):想要让AOP做的事情.
-
JoinPoint(连接点):允许AOP通知的地方,比如,在方法被调用前 检查权限,这个“方法被调用前”就是一个JoinPoint.
-
Pointcut(切入点):用于筛选JoinPoint的条件。只有符合Pointcut 条件的JoinPoint才会执行Advice.
-
Aspect(切面):一个包含Advice和Pointcut的集合,完整地定义了 符合什么条件时做什么事。
要想知道AOP可以用在哪些场景,我们需要从AOP其中一个概念入手—— Advice(通知)。我们简单回顾一下。
-
Before:在目标方法执行前调用Advice
-
After[finally]:在目标方法执行完成后调用Advice
-
After-Returning:在目标方法成功执行后调用Advice
-
After-Throwing:在目标方法抛出异常后调用Advice
-
Around:一般解释为环绕/包裹目标方法调用Advice,是可定制化调用 的Advice
AOP的适用场景
Before可以在目标方法执行前做一些事情,如解析请求参数、进行权限检 查等;
After可以在目标方法执行完成后记录一些日志;
After-Returning可以 与Before配合计算目标方法执行时间;
After-Throwing可以在目标方法抛出异 常后做一些处理;
而Around基本上可以做以上所有的事情。
根据AOP的能力与特点,我们通常会在以下场景中使用AOP:
-
参数检查
-
日志记录
-
异常处理
-
性能统计
除了上面这些基础功能,还可以利用AOP做一些更加复杂的通用处理:
-
事务控制
-
缓存处理
-
权限控制
案例
1.引入AOP依赖
2.创建AspectController类
3.创建一个切面类WebAspect:
4.在类上加上@Aspect注解,可以用来标识该类为一个AOP的切面。
日志记录
在AspectController类中添加如下接口:
然后在WebAspect类中添加如下代码
before方法中获取了请求路径(path)、完整类路径、目标方法名、参数 信息。after方法中打印了目标方法名。afterReturning方法中打印了目标方 法的返回值。
@Pointcut用来定义切点;execution是用来匹配连接点的执行方法; public代表要匹配访问权限为public的方法;第一个代表返回值为任意 类型;com.shuijing.boot.aop为包路径;第二个代表前面包路径下的任 意类;第三个*代表任意方法;(..)代表任意参数。
4.执行顺序
-
同一切面内的执行顺序
-
不同切面间的执行顺序
同一切面内的执行顺序:
先执行 before方法,再执行afterReturning/afterThrowing方法,最后执行after方 法。around方法早于before方法开始执行,并且晚于after方 法结束执行,刚好将其他通知完全包裹了起来
不同切面间的执行顺序:
Spring中默认的执行顺序其实就是Bean初始化的顺序。而Spring中的加载顺序是根据类名升序 排列的,很明显,Three按字母排序会排在Two前面。@Order来解决顺序问题。
5.原理
Spring的AOP是用代理的方式实现的。每个切面都是Spring容器中的一个 Bean,在目标方法被调用时,Spring把切面应用到目标对象上,为目标对象动 态创建代理,这个过程叫作Weaving(织入)。切面会在指定(符合切点条 件)的连接点织入目标对象中。
当调用者调用目标对象时,调用请求会被代理类拦截,而在目标对象真正被调用之前,会先织入切面逻辑。当应用需要目标对象时, Spring才会创建代理对象,因为Spring采用的是运行期织入的实现方式。