后端Web之Spring的AOP面向切面编程

目录

概述

入门

概念

通知

切入点表达式

连接点


概述

AOP即面向切面编程(Aspect-Oriented Programming),它是spring框架的第二大核心(第一大核心是IOC控制反转),它是一种编程范式,它允许开发者将横切关注点(如日志记录、事务管理、安全性等)与业务逻辑分离,从而提高代码的模块化和可维护性。AOP是面向对象编程(OOP)的补充,它通过预编译方式(如AspectJ)或运行时动态代理(如Spring AOP)实现程序功能的统一维护。

简单来说,AOP就是面向特定方法编程。可以减少重复代码、提高开发效率。在不修改业务逻辑代码的情况下,通过动态代理技术对已有方法进行增强,实现无侵入式的代码复用。

入门

场景:项目中部分功能运行较慢,需要定位执行耗时较长的业务方法,此时需要统计每一个业务方 法的执行耗时。我们一般会想到,在方法开始前记录时间,在方法结束时再记录一次,这样两次时间的差就是方法执行的时间。这对于一两个方法是可以用的,但如果有几十甚至几百个方法呢?

我们不可能对每个方法都进行改造。此时我们可以抽离出记录时间的逻辑,单独创建一个模板方法。每个业务方法运行时,都去运行这个模板方法,这样就能简单快速的记录每个业务方法的运行时间。

实现:动态代理是面向切面编程最主流的实现。而SpringAOP是Spring框架的高级技术,旨在管理bean对象的过程中,主要通过底层的动态代理机制,对特定的方法进行编程。

使用:导入AOP依赖,注解@Aspect表示这是一个AOP类,注解@Around表示针对这个类进行编程,如果要统计别的类执行时间,更换这个类即可。这里 * 号表示对service包下所有类都统计执行时间

这时我们在浏览器发送请求后,就能统计到方法耗时:

这样我们没有修改原有代码,也实现了对方法统计时间的功能,这就是AOP面向切面编程,这只是AOP的冰山一角。它还可以记录操作日志、项目权限控制、事务管理等。spring的事务管理底层就是基于AOP完成的。

概念

连接点(Joinpoint):指程序中可以被切面插入的点,如方法调用或属性访问。即可以被AOP控制的方法(暗含方法执行时的相关信息),比如案例中的service包下所有的方法就是连接点

通知(Advice):在连接点处执行的代码,包括前置通知(Before Advice)、后置通知(After Advice)、返回通知(After Returning Advice)、异常通知(After Throwing Advice)和环绕通知(Around Advice) 。也就是重复的逻辑、共性的功能

切入点(Pointcut):用于定义哪些连接点上应该应用通知,通常通过切入点表达式来指定。

切面(Aspect):表示一个模块化的横切关注点,它包括了连接点和通知。可以通过配置文件或注解等方式定义切面。

织入(Weaving):将切面应用到目标对象并创建新的代理对象的过程,可以在编译时、类加载时或运行时完成。

AOP执行流程:

springAOP基于动态代理技术:程序运行时会为目标对象生成一个代理对象,再将通知结合代理对象,就完成了功能增强。此时程序将不再运行原有的对象,而是运行这个代理对象

 AOP类如下:

程序运行时通过@Autowired注入的对象其实是代理对象,这个代理对象已经完成了方法增强,这样运行list方法时,就能统计出方法耗时了。

通知

另外,@PointCut注解的作用是将公共的切点表达式抽取出来,需要用时引入用该切点表达式即可

通知顺序:当有多个切面的切入点都匹配到了目标方法,目标方法运行时,多个通知方法都会被执行。

这里定义了多个切面类,执行顺序如下:

可以看到,不同切面类中,默认按照切面类的类名字母排序。目标方法前的通知方法是字母排名靠前的先执行,而目标方法后的通知方法是字母排名靠前的后执行

@order注解可以控制切面类的执行顺序,对于前通知,括号内数字小的先执行,后通知则相反

切入点表达式

切入点表达式(Pointcut Expression)是AOP中用于定义哪些方法将被增强(即哪些方法将被切面所拦截)的一种表达式语言。它允许开发者指定一组特定的连接点,这些连接点可以是方法的调用、方法的执行、属性的访问等。常见形式如下:

1. execution(......): 根据方法的签名来匹配 

2.annotattion(......) : 根据注解匹配

书写建议:

  • 所有业务方法名在命名时尽量规范,方便切入点表达式快速匹配。如:查询类方法都是find开头,更新类方法都是update开头。
  • 描述切入点方法通常基于接口描述,而不是直接描述实现类以增强拓展性。
  • 在满足业务需要的前提下,尽量缩小切入点的匹配范围。如:包名匹配尽量不使用...,使用*匹配单个包。

连接点

在Spring中用JoinPoint抽象了连接点,用它可以获得方法执行时的相关信息,如目标类名、方法名、方法参数等。对于@Around 通知,获取连接点信息只能使用 ProceedingJoinPoint。对于其他四种通知, 获取连接点信息只能使用JoinPoint ,它是ProceedingJoinPoint 的父类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值