概述
动态代理是面向切面编程最主流的实现。而SpringAOP是Spring框架的高级技术,旨在管理bean对象的过程中,主要通过底层的动态代理机制,对特定的方法进行编程。
入门
导入依赖
<!-- aop-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
编写AOP
@Component
@Aspect
public class TimeAspect {
@Around("execution(* com.itheima.service.*.*(..))")//切入点表达式
public Object recordTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
long begin = System.currentTimeMillis();
Object object = proceedingJoinPoint.proceed(); //调用原始方法运行
long end = System.currentTimeMillis();
log.info(proceedingJoinPoint.getSignature()+"执行耗时: {}ms", end - begin);
return object;
}
核心概念
过程
进阶AOP
通知类型
@PointCut
通知顺序
不同切面类中,默认按照切面类的类名字母排序:
目标方法前的通知方法:字母排名靠前的先执行
目标方法后的通知方法:字母排名靠前的后执行
@Order(数字)
用 @Order(数字) 加在切面类上来控制顺序
目标方法前的通知方法:数字小的先执行
目标方法后的通知方法:数字小的后执行
切入点表达式
切入点表达式:描述切入点方法的一种表达式
作用:主要用来决定项目中的哪些方法需要加入通知
常见形式: execution(……):根据方法的签名来匹配
@annotation(……) :根据注解匹配
切入点表达式语法
通配符
切入点表达式-@annotation
@Retention(RetentionPolicy.RUNTIME)//什么时候生效,运行时生效
@Target(ElementType.METHOD)//当前注解可作用在方法上
public @interface Log {
}
@Around("@annotation(com.itheima.anno.Log)")
public Object recordLog(ProceedingJoinPoint JoinPoint) throws Throwable {
//操作人的id
//获取请求头的jwt令牌,解析令牌
String jwt =request.getHeader("token");
System.out.println(jwt);
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=JSON.toJSONString(result);
//操作耗时
Long costime=end-begin;
//操作日志
OperateLog operateLog=new OperateLog(null,operateUser,operateTime,className,methodName,methodParams,returnValue,costime);
operateLogMapper.insert(operateLog);
return result;
}