Spring AOP(概念,使用)

目录

  • [Spring AOP](#Spring AOP)

Spring AOP

AOP是什么

  • Aspect Oriented Programminig(面向切面编程)
  • 切面 指的是某一类特定问题,比如说登录拦截器,就是对"登录校验",这一类问题的统一处理
  • 所以,拦截器是AOP的一种应用
  • AOP是一种思想,是对某一类事情的集中处理

什么是Spring AOP

  • AOP是一种思想,它的实现方法有很多,有Spring AOP,也有AspectJ ,CGLIB等。


AOP可以做到在不改动这些原始方法的基础上,针对特定的方法进行功能的增强

AOP的作用:在程序运行期间在不修改源代码的基础上,对已有的方法进行增强(无侵入性:解耦)

AOP实际开发流程

1. 引入依赖

在pom.xml文件中添加配置

xml 复制代码
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 编写AOP程序

业务:记录Controller中每个方法的执行时间

java 复制代码
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Slf4j
@Aspect
@Component
public class TimeAspect {
 /**
 * 记录⽅法耗时
 */
 @Around("execution(* com.example.demo.controller.*.*(..))")
 	public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {
 //记录⽅法执⾏开始时间
 		long begin = System.currentTimeMillis();
 //执⾏原始⽅法
		 Object result = pjp.proceed();
 //记录⽅法执⾏结束时间
 		long end = System.currentTimeMillis();
 //记录⽅法执⾏耗时
		 log.info(pjp.getSignature() + "执⾏耗时: {}ms", end - begin);
 return result;
 }
}

Spring AOP详解

  1. @Aspect: 标识这是一个切面类
  2. @Around:环绕通知,在目标方法执行前后都会被执行。
  3. ProceedingJoinPoint.proceed() 让原始方法执行

Spring AOP中的核心概念

  1. 切点(Pointcut)
    提供一组规则,告诉程序对哪些方法来进行增强
  1. 连接点

    满足切点表达式规则的方法
    例如

    切点表达式:英雄联盟全部射手

    连接点:希维尔,艾希等各个射手

  2. 通知(Advice)

    具体要做的工作

  3. 切面(Aspect)

    切面 = 切点 + 通知
    切面所在的类,一般称为切面类

Spring AOP的通知类型

六种类型

上⾯我们讲了什么是通知, 接下来学习通知的类型. @Around 就是其中⼀种通知类型, 表⽰环绕通知.
Spring中AOP的通知类型有以下⼏种:
• @Around: 环绕通知, 此注解标注的通知⽅法在⽬标⽅法前, 后都被执⾏
• @Before: 前置通知, 此注解标注的通知⽅法在⽬标⽅法前被执⾏
• @After: 后置通知, 此注解标注的通知⽅法在⽬标⽅法后被执⾏, ⽆论是否有异常都会执⾏
• @AfterReturning: 返回后通知, 此注解标注的通知⽅法在⽬标⽅法后被执⾏, 有异常不会执⾏
• @AfterThrowing: 异常后通知, 此注解标注的通知⽅法发⽣异常后执⾏

程序发生异常的情况下:

  1. @AfterReturning 标识的通知方法不会执行,@AfterThrowing 标识的通知方法执行
  2. @Around环绕通知中原始方法调用时有异常,通知中的环绕后的代码逻辑也不会在执行了

注意事项

  1. 环绕通知⽅法的返回值, 必须指定为Object, 来接收原始⽅法的返回值, 否则原始⽅法执⾏完毕, 是获取不到返回值的.
  2. @Around 环绕通知需要调用ProceedingJoinPoint.proceed() 来让原始⽅法执⾏, 其他通知不需要考虑⽬标⽅法执⾏.
  3. 一个切面类可以用多个切点
@PointCut

上⾯代码存在⼀个问题, 就是存在⼤量重复的切点表达式 execution(* com.example.demo.controller.. (...)) , Spring提供了 @PointCut 注解, 把公共的切点表达式提取出来, 需要⽤到时引⽤该切⼊点表达式即可.

上述代码就可以修改为:

java 复制代码
@Aspect
@Component
public class AspectDemo {
 //定义切点(公共的切点表达式)
 @Pointcut("execution(* com.example.demo.controller.*.*(..))")
 private void pt(){}
 //前置通知
 @Before("pt()")
 public void doBefore() {
 //...代码省略
 }
 //后置通知
 @After("pt()")
 public void doAfter() {
 //...代码省略
 }
 //返回后通知
 @AfterReturning("pt()")
 public void doAfterReturning() {
 //...代码省略
 }
 //抛出异常后通知
 @AfterThrowing("pt()")
 public void doAfterThrowing() {
 //...代码省略
 }
 //添加环绕通知
 @Around("pt()")
 public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
 //...代码省略
 }
}
@Order(切面优先级)

存在多个切⾯类时, 默认按照切⾯类的类名字⺟排序:

• @Before 通知:字⺟排名靠前的先执⾏

• @After 通知:字⺟排名靠前的后执⾏

但这种⽅式不⽅便管理, 我们的类名更多还是具备⼀定含义的.

Spring 给我们提供了⼀个新的注解, 来控制这些切⾯通知的执⾏顺序: @Order

该注解标识的切⾯类, 执⾏顺序如下:

• @Before 通知:数字越⼩先执⾏

• @After 通知:数字越⼤先执⾏

相关推荐
爱尚你19936 分钟前
Java 泛型与类型擦除:为什么解析对象时能保留泛型信息?
java
电商数据girl29 分钟前
酒店旅游类数据采集API接口之携程数据获取地方美食品列表 获取地方美餐馆列表 景点评论
java·大数据·开发语言·python·json·旅游
CircleMouse29 分钟前
基于 RedisTemplate 的分页缓存设计
java·开发语言·后端·spring·缓存
ktkiko1135 分钟前
顶层架构 - 消息集群推送方案
java·开发语言·架构
zybsjn40 分钟前
后端系统做国际化改造,生成多语言包
java·python·c#
Unity官方开发者社区1 小时前
《Cryptical Path》开发诀窍:像玩游戏一样开发一款类Rogue游戏
java·游戏·玩游戏
_星辰大海乀1 小时前
表的设计、聚合函数
java·数据结构·数据库·sql·mysql·数据库开发
IT成长史1 小时前
deepseek梳理java高级开发工程师微服务面试题-进阶版
java·spring cloud·微服务
zkmall2 小时前
Java + 鸿蒙双引擎:ZKmall开源商城如何定义下一代B2C商城技术标准?
java·开源·harmonyos
陌路物是人非2 小时前
uniapp取消浏览自动填充
java·服务器·uni-app