概述
AOP 是 spring 框架中重要的一环, 全称:Aspect Orient Programming,AOP 是一种设计思维,意为面向切面编程,它是面向对象编程 (OOP) 的一种补充和欠缺. 它以通过预编译形式和运行期动静代理形式两种形式实现在不批改源代码的状况下给程序动静对立增加额定性能的一种技术.
oop 与 aop
两者的区别能够了解为:
oop 是动态固定的, 有多少模块多少对象, 怎么执行都是运行前写好的;
aop 是动静扩大的, 能够在对象运行时去如果一些扩大的性能或是管制对象执行某些性能.
利用场景
我的项目中个别有外围业务与非核心业务, 而非核心业务个别通过特定形式切入零碎 –> 个别就是借助于 aop 来实现.
aop 次要基于 ocp(开闭准则)– 对扩大凋谢, 对批改敞开 – 简略来说就是增加性能时, 不能扭转原有外围业务代码, 只能在其上增加.
aop 能够实现, 如: 日志解决 / 事务处理 / 缓存解决等等.
原理剖析
AOP 底层基于代理机制实现性能扩大, 有两种实现形式:
1) 如果指标对象 (被代理对象) 实现接口, 则底层能够采纳 JDK 动静代理机制为指标对象创立代理对象(指标类和代理类会实现独特接口
2) 如果指标对象(被代理对象) 没有实现接口, 则底层能够采纳 CGLIB 代理机制为指标对象创立代理对象(默认创立的代理类会继承指标对象类型)
Spring boot2.x 当前的版本中 AOP 当初默认应用的 CGLIB 代理, 如果须要应用 JDK 动静代理能够在配置文件 (applicatiion.properties) 中进行如下配置:
spring.aop.proxy-target-class=false
相干术语
1) 切面 (aspect): 横切面对象, 个别为一个具体类对象(能够借助 @Aspect 申明)—AOP 对象
2) 告诉(Advice): 在切面的某个特定连接点上执行的动作(扩大性能),例如 around,before,after 等 —AOP 办法
3) 连接点(joinpoint): 程序执行过程中某个特定的点,个别指被拦挡到的的办法 — 指标办法
4) 切入点(pointcut): 对多个连接点(Joinpoint) 一种定义, 个别能够了解为多个连接点的汇合 — 指标办法汇合
利用实例
切面(aspect)
@Aspect 注解形容的类为 spring 容器的一个切面对象类(此类型中封装切入点与告诉办法)
- 1)切入点: 要执行拓展业务的办法的汇合
- 2)告诉办法: 封装了在切入点办法上要执行的拓展业务办法
切入点
@Pointcut 注解用于形容切入点(在那些点上执行拓展业务)
bean(bean 类型名字): 为一种切入点表达式 (这个表达式中定义了那些 bean 对象的办法要进行性能拓展)
例如:bean(sysUserServiceImpl)示意名字为 sysUserServiceImpl 的 bean 对象中所有办法的汇合为切入点, 也就是说 sysUserServiceImpl 对象中任意办法执行时都要进行性能扩大
告诉办法
@Around 注解形容的办法为一个告诉办法(服务增益办法), 此办法外部能够做服务增益(拓展业务)
@Around 注解外部要指定切入点表达式, 在此切入点表达式对应的切入点办法上做性能扩大
@param jp 示意连接点, 是动静确定的, 用于封装正在执行的切入点办法信息
@return 指标办法的执行后果
@throws Throwable 告诉办法执行过程中呈现的异样
ProceedingJoinPoint 类为一个连接点类型,此类型的对象用于封装要执行的指标办法相干的一些信息。只能用于 @Around 注解形容的办法参数
// 执行指标办法
Object result = jp.proceed();// 最终会调用指标办法(两头可能会其余告诉办法)
加强
切面告诉
切面告诉共有五种:
@Before/@AfterReturning/@AfterThrowing/@After/@Around(优先级最高)
留神: 切面并不是所有告诉都要应用, 应用什么告诉由业务决定.
五个告诉的执行程序如下:
@Around–>@Before–> 指标办法 –>@Around–>@After–>@AfterReturning(失常状况)/@AfterThrowing(异常情况)
切入点表达式
1) bean: 用于匹配指定 bean 对象的所有办法
bean(bean 对象名)
bean 表达式外部的对象是由 spring 容器治理的一个 bean 对象, 表达式外部的名字应该是 spring 容器中某个 bean 的 name
3) within: 用于匹配指定包下所有类内的所有办法
within(包名 + 类名)– 不罕用
5) execution: 用于按指定语法规定匹配到具体方法
execution(返回值类型 包名. 类名. 办法名(参数列表))– 不罕用
7) @annotation: 用于匹配指定注解润饰的办法
@annotation(注解全类名) 匹配有此注解形容的办法
咱们须要本人定义注解, 当应用这个注解润饰的类就是指标对象
bean/within 表达式个别利用于类级别,实现粗粒度的切入点定义 – 罕用 bean
execution/@annotation 表达式利用于办法级别,实现细粒度的切入点表达式定义 – 罕用 @annotation
切面优先级设置
当多个切面作用于同一个指标对象办法时,这些切面会构建成一个切面链, 切面的优先级须要借助 @Order 注解进行形容,数字越小优先级越高,默认优先级比拟低.