Spring AOP 01

概述

AOP是spring框架中重要的一环,全称:Aspect Orient Programming,AOP是一种设计思想,意为面向切面编程,它是面向对象编程(OOP)的一种补充和完善.它以通过预编译方式和运行期动态代理方式两种方式实现在不修改源代码的情况下给程序动态统一添加额外功能的一种技术.

本文主要说的是现在常用的整合AspectJ框架.

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)通知方法:封装了在切入点方法上要执行的拓展业务方法

image

切入点

@Pointcut 注解用于描述切入点(在那些点上执行拓展业务)

bean(bean类型名字):为一种切入点表达式(这个表达式中定义了那些bean对象的方法要进行功能拓展)
例如:bean(sysUserServiceImpl)表示名字为sysUserServiceImpl的bean对象中所有方法的集合为切入点,也就是说sysUserServiceImpl对象中任意方法执行时都要进行功能扩展

image

通知方法

@Around 注解描述的方法为一个通知方法(服务增益方法),此方法内部可以做服务增益(拓展业务)
@Around 注解内部要指定切入点表达式,在此切入点表达式对应的切入点方法上做功能扩展
@param jp 表示连接点,是动态确定的,用于封装正在执行的切入点方法信息
@return 目标方法的执行结果
@throws Throwable 通知方法执行过程中出现的异常

image
ProceedingJoinPoint类为一个连接点类型,此类型的对象用于封装要执行的目标方法相关的一些信息。只能用于@Around注解描述的方法参数

//执行目标方法
Object result = jp.proceed();//最终会调用目标方法(中间可能会其他通知方法)

增强

切面通知

切面通知共有五种:
@Before/@AfterReturning/@AfterThrowing/@After/@Around(优先级最高)
注意:切面并不是所有通知都要使用,使用什么通知由业务决定.

五个通知的执行顺序如下:
Spring AOP 01_第1张图片
@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注解进行描述,数字越小优先级越高,默认优先级比较低.

你可能感兴趣的:(aop)