@Slf4j @Component @Aspect//aop类 public class TimeAspect { /*Around 环绕通知 用ProceedingJoinPoint @Before 前置通知 用JoinPoint(是ProceedingJoinPoint的父类型),用它可以获得方法执行的相关信息,如目标类名,方法名,方法参数 @After 后置通知 用JoinPoint ,jpinPoint.getTargrt(),getClass().getName();(获取目标类名) @AfterReturning 返回后通知 用JoinPoint ,jpinPoint.getSignstrue();(获取目标方法签名) *@AfterThrowing 异常后通知 用JoinPoint ,jpinPoint.getSignature().getName();(获取目标方法名) ,jpinPoint.getArgs();(获取目标方法运行参数) */ //@annotation切入点表达式,用于匹配有特点注解的方法 //@annotation(com.itheima.aop.MyLog)仅仅匹配上面加有@MyLog注解的方法 //execution切入点表达式,主要根据方法的返回值,包名,类名,方法名,方法参数等信息来匹配 // 例如:execution(void com.itheima.service.impl.empserviceimpl.getById(java.lang.Integer));execution切入点表达式 @Around("execution(* com.itheima.service.*.*(..))") //切入点表达式 public Object recordTime(ProceedingJoinPoint joinPoint) throws Throwable { long begin=System.currentTimeMillis(); Object result = joinPoint.proceed();//目标方法放行 long end =System.currentTimeMillis(); log.info(joinPoint.getSignature()+"方法执行耗时:{}ms",end-begin); return result; } }
==================================================================================================================================================案例:
记录表:
-- 操作日志表 create table operate_log( id int unsigned primary key auto_increment comment 'ID', operate_user int unsigned comment '操作人ID', operate_time datetime comment '操作时间', class_name varchar(100) comment '操作的类名', method_name varchar(100) comment '操作的方法名', method_params varchar(1000) comment '方法参数', return_value varchar(2000) comment '返回值', cost_time bigint comment '方法执行耗时, 单位:ms' ) comment '操作日志表';
OperateLog实体类:
OperateLogMapper接口:
注解Log:(不要忘记去对应方法上加@Log注解,否则@annotation无效)
LogAspect切面类:
{ @Autowired private HttpServletRequest request; @Autowired private OperateLogMapper operateLogMapper; @Around("@annotation(com.itheima.anno.Log)") public Object recordLog(ProceedingJoinPoint joinPoint) throws Throwable { //当前登陆人ID(获取请求头中的jwt令牌,解析令牌获取id) String jwt = request.getHeader("token"); Claims claims = JwtUtils.parseJWT(jwt); Integer operateUser=(Integer) claims.get("id"); //操作时间 LocalDateTime operaTime = 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,operaTime,className,methodName,methodParams,returnValue,costTime); operateLogMapper.insert( operateLog); log.info("AOP记录操作日志:{}",operateLog); return result; } }