JavaWeb开发_Web后端_AOP

news/2024/12/5 5:30:58/

JavaWeb开发_Web后端_AOP

  • AOP基础
    • AOP快速入门
  • AOP进阶
    • 通知类型
    • 通知顺序
    • 切入点表达式
    • 连接点
  • 案例
  • 来源

AOP基础

AOP快速入门

依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

TimeAspect:

@Slf4j
@Component
@Aspect // AOP类
public class TimeAspect {@Around("execution(* com.itheima.service.*.*(..))") // 切入点表达式public Object recordTime(ProceedingJoinPoint joinPoint) throws Throwable {// 1. 记录开始时间long begin = System.currentTimeMillis();// 2. 调用原始方法运行Object result = joinPoint.proceed();// 3. 记录结束时间, 计算方法执行耗时long end = System.currentTimeMillis();log.info(joinPoint.getSignature()+"方法执行耗时: {}ms", end-begin);return result;}
}

AOP进阶

通知类型

类型解释
@Around在目标方法前后执行
@Before方法前执行
@After方法后运行, 无论是否有异常都会执行
@AfterReturning方法后运行. 有异常不会运行
@AfterThrowing方法后运行, 有异常才会运行
@Slf4j
@Component
@Aspect
public class MyAspect1 {@Pointcut("execution(* com.itheima.service.impl.DeptServiceImpl.*(..))")public void pt(){}// 返回值任意, 方法任意, 形参任意@Before("pt()")public void before(){log.info("before ...");}@Around("pt()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {log.info("around before ...");Object result = joinPoint.proceed();log.info("around after ...");return result;}@After("pt()")public void after(){log.info("after ...");}@AfterReturning("pt()")public void afterReturning(){log.info("afterReturning ...");}@AfterThrowing("pt()")public void afterThrowing(){log.info("afterThrowing ...");}
}

通知顺序

  1. 不同切面类中, 默认按照切面类的类名字母排序
  2. 用@Order(数字)加在切面类上来控制顺序

切入点表达式

execution:

// ? 表示可省略, 包名.类名. 不建议省略
// execution(访问修饰符? 返回值 包名.类名.?方法名(方法参数) throws 异常?)
@Pointcut("execution(void com.itheima.service.impl.DeptServiceImpl.delete(java.lang.Integer))")// * 单个独立的任意符号,可以通配任意返回值、包名、类名、方法名、任意类型的一个参数,也可以通配包、类、方法名的一部分
execution(* com.*.service.*.update*(*))
// .. 多个连续的任意符号,可以通配任意层级的包,或任意类型、任意个数的参数
execution(* com.itheima..DeptService.*(..))

@annotation:

// 自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyLog {
}
// @annotation
@Pointcut("@annotation(com.itheima.aop.MyLog)")

连接点

  • @Around通知, 只能使用ProceedingJoinPoint
  • 其他四种通知, 只能使用JoinPoint, 是ProceedingJoinPoint的父类型
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {log.info("around before ...");// 1. 获取目标对象的类名String className = joinPoint.getTarget().getClass().getName();log.info("目标对象的类名: {}", className);// 2. 获取目标方法的方法名String methodName = joinPoint.getSignature().getName();log.info("目标方法的方法名: {}", methodName);// 3. 获取目标方法运行时传入的参数Object[] args = joinPoint.getArgs();log.info("目标方法运行时传入的参数: {}", Arrays.toString(args));// 4. 放行 目标方法执行Object result = joinPoint.proceed();// 5. 获取目标方法运行的返回值log.info("目标方法运行的返回值: {}", result);log.info("around after ...");return result;
}

案例

@Slf4j
@Component
@Aspect
public class LogAspect {@Autowiredprivate HttpServletRequest request;@Autowiredprivate OperateLogMapper operateLogMapper;@Around("@annotation(com.itheima.anno.Log)")public Object recordLog(ProceedingJoinPoint joinPoint) throws Throwable {// 操作人ID - 当前登录员工ID// 获取请求头中的jwt令牌, 解析令牌String jwt = request.getHeader("token");Claims claims = JwtUtils.parseJWT(jwt);Integer operateUser = (Integer) claims.get("id");// 操作时间LocalDateTime operateTime = LocalDateTime.now();// 操作类名String className = joinPoint.getTarget().getClass().getName();// 操作方法名String methodName = joinPoint.getSignature().getName();// 操作方法参数Object[] args = joinPoint.getArgs();String methodParams = Arrays.toString(args);Long begin = System.currentTimeMillis();Object result = joinPoint.proceed();Long end = System.currentTimeMillis();// 方法返回值String returnValue = JSONObject.toJSONString(result);// 操作耗时Long costTime = end - begin;// 记录操作日志OperateLog operateLog = new OperateLog(null, operateUser, operateTime, className, methodName, methodParams, returnValue, costTime);operateLogMapper.insert(operateLog);log.info("AOP操作记录日志: {}", operateLog);return result;}}

来源

黑马程序员. JavaWeb开发教程


http://www.ppmy.cn/news/224917.html

相关文章

安装第三方库时的问题—复现带setup.py的项目

目录 题目分析&#xff1a; 正片开始&#xff1a; 题目分析&#xff1a; 事情的经过大致是这样&#xff1a; 今天在github上拿到一个处理时间序列的迁移学习项目的复现代码&#xff0c;项目文件如下所示&#xff1a; 或者我们来关注一下tl4sm这个文件夹里的东西&#xff1…

台式计算机可以链接蓝牙音响吗,台式电脑可以连接蓝牙音响吗

大家好&#xff0c;我是时间财富网智能客服时间君&#xff0c;上述问题将由我为大家进行解答。 台式电脑可以连接蓝牙音响。蓝牙是一种无线通讯技术&#xff0c;只要是电脑&#xff0c;就肯定是可以用的。但台式机&#xff0c;一般没有内置蓝牙模块&#xff0c;所以需要单独购买…

海睿思分享 | 低代码开发直面行业变革:革新,创新?

软件体系结构从单体集群服务时期&#xff0c;历经领域驱动设计、微服务架构等阶段&#xff0c;软件产品的开发过程的变革正在潜移默化地进行。 在软件逻辑架构设计、物理架构设计、构建与部署这一系列化的过程中&#xff0c;存在可缩减的设计与开发成本&#xff0c;曾经看似不可…

计算机软件的输出设备有哪些,计算机输出设备有哪些

计算机输出设备主要有打印机、显示器、绘图仪、音箱、电视机、喇叭和录像机等。 (l)显示器。显示器又称为监视器&#xff0c;主要用于显示各种数据或者画面&#xff0c;是人与微机之间交换信息的窗口。显示器可以及时地反映出微型机的工作情况和运行结果&#xff0c;并提示用户…

计算机多媒体设备是啥,什么是多媒体教学设备?多媒体教学设备有哪些??

原标题&#xff1a;什么是多媒体教学设备&#xff1f;多媒体教学设备有哪些&#xff1f;&#xff1f; 多媒体教学设备使用 一、我校多媒体教室的使用的注意事项 如何合理利用设备&#xff0c;最大限度发挥设备的作用&#xff0c;就是我们培训的主要目的&#xff0c;希望通过培训…

PHASOUND发布超旗舰铂金系列,高端酒吧音响设备还需要买进口品牌吗

2021开年&#xff0c;PHASOUND就发布了超旗舰铂金Platinum系列超强性能的大型线阵列扩声系统&#xff0c;主要有2个型号P122(双12三分频线阵列音箱&#xff09;&#xff0c;P182&#xff08;双18低音炮音箱&#xff09; PHASOUND表示&#xff1a;这个象征国产最强技术世界顶级…

IO设备的类型

参考书籍&#xff1a;《计算机操作系统》 IO设备的类型&#xff1a; 1 按照设备的使用特性分类&#xff1a; 1&#xff09;存储设备 也称为外存或者后备存储器、辅助存储器&#xff0c;。是计算机系统用以存储信息的主要设备。该类设备存取速度较内存慢&#xff0c;但容量比…

dlna 电脑连r1_某讯R1音响——版本升级和安装DLNA细致教程

垃圾佬的日常折腾。 购买理由 自从某讯倒了后,世面上出现大量价格低廉的好产品,R1音响就是其中一个,虽然服务器倒了,但只有85!只有85!还包邮!就可以拥有一个哈曼Infinity定制的发声单元,还有啥自行车呀 前言 因为据广大网友亲身试验,版本号3448的声音有很大的提升,声…