Spring Aop切面编程初解

概要

简单记录对AOP的理解,包括使用场景和实现原理。

场景描述:如果不使用AOP概念,怎么实现所有接口的调用日志记录?

第一反应就是编写一个公共方法,在每个接口方法最开始调用一次,结束时调用一次,异常时调用一次。但是缺点也很明显,所有的方法都要写重复的代码,而且侵入性非常强。
而使用AOP就简单很多,不需要在接口方法中添加任何代码。只需要以下四步:

第1步:引入AOP依赖

在这里插入图片描述

第2步:创建一个类,并使用@Aspect和@Component进行修饰

在这里插入图片描述

第3步:在类里面创建一个方法,使用@Pointcut修饰,参数填写需要插入切面的切点

注: 参数可以理解为包路径或者类路径,这里写错的话,后续的通知就无法执行。
示例中是对controller下所有的接口方法都进行织入

第4步:再创建一个方法,用@Around修饰定义成通知,参数填写切点

通知也就是具体的执行逻辑,而@Around修饰符是为了控制执行时机,还有前置通知、后置通知等其他类型

关键概念解释

根据以上四步就完成了一个切面的定义,现在从第四步由后向前依次进行概念解释

1、通知及通知类型

示例中的@Around就是环绕通知,通知也有被成为增强,即对目标函数进行增强的函数逻辑。
通知一般分为以下几种:
环绕通知( @Around)。在连接点前后执行通知类型,用于在方法调用前后自定义一些操作,例如在方法调用前后添加日志记录、事务控制等。
** 前置通知( @Before)**。无论异常都执行,在目标方法执行前执行的通知类型,用于在执行目标方法前进行一些操作,例如参数校验、日志记录等。
后置通知( @After )。方法异常则不执行,在目标方法执行后执行的通知类型,用于在目标方法执行结束后进行一些操作,例如日志记录、事务提交等。
最终通知( @AfterRunning )。无论异常都执行,在目标方法执行后返回结果时执行的通知类型,用于获取目标方法返回的结果并进行一些操作,。
异常通知( @AfterThrowing )。方法异常才执行,在目标方法执行发生异常时执行的通知类型,用于在目标方法抛出异常后执行特定的操作。

2、切点 @Pointcut

用于定义切点,切点可以理解为连接点,用于将通知目标对象连接起来,也可以理解在原有的执行流程中的指定位置插入通知函数并执行。
而切点注解的参数就是指具体的类,如示例中切点表达式直接写了类的包路径。
需要说明的是,切点不是只有一个,而是根据切点表达式匹配到的所有位置,比如只有一个controller类,内部有两个接口函数,那么就是有两个切点
先对比一下执行节点:
在这里插入图片描述

切点表达式的值就是controller所在的包的全路径,表达式中(**)是指类中的所有方法都作为切点

3、切面

简单理解就是使用@Aspect和@Component注解修饰的类就是切面。切面的概念并不复杂,但是执行流程需要理解。
1、Spring Boot启动时会进行一系列的初始化配置,包括加载启动类、加载配置文件、创建Spring容器等步骤。在这些步骤中,特别是当Spring容器创建完成后,Spring AOP会开始工作。
2、当Spring容器中的Bean被创建和初始化时,如果这些Bean被标记为需要进行AOP代理(例如,它们所在的类有@Aspect注解,或者它们的方法匹配了某个切点表达式),Spring AOP会创建这些Bean的代理对象。在创建代理对象的过程中,Spring AOP会解析切点表达式,确定哪些方法需要被拦截,并生成相应的代理逻辑。

4、织入

织入是指将通知逻辑与目标对象的切点进行匹配和关联的操作,而spring和springBoot的织入有一点点不同。
spring中如果主类现实了任意接口 则使用JDK动态代理 否则使用CGLib。
springboot 中默认就使用CGLib 。

JDK动态代理的实现是基于Java的反射机制,通过反射在运行时动态生成代理类的字节码。
CGLIB动态代理则是通过继承目标类生成子类的方式来创建代理对象,子类会重写父类的所有非final方法,并在其中采用方法拦截的技术来拦截父类的所有方法调用。

两种方式各有优缺点:
由于JDK动态代理依赖于反射机制,因此在调用代理方法时性能上可能不如CGLIB。
CGLIB动态代理通过直接操作字节码生成新的类,避免了反射的开销。
所以,springboot 选择了CGLib ,至于JDK动态代理无法在本篇文章展开,会另外编写详细描述。

适用场景

面向切面编程的优点毋庸置疑,灵活、解耦、复用、非入侵,很多插件中都在使用,比如MyBatis。
一般实际应用场景有以下几个:
日志记录、异常处理、权限验证、缓存处理、事务处理、数据持久化等等。
此前在使用filter-group-vue组件的时候,前端表格的筛选条件统一使用树形结构,而后端则是在@Before通知中进行判断和解析成map数据结构。

以上文章中如有问题,欢迎留言或私信指出

  • 30
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值