1.创建数据表
首先设计存储方法执行结果的数据表
create table operate_log
(
id int unsigned auto_increment comment 'ID'
primary key,
class_name varchar(100) null comment '操作的类名',
method_name varchar(100) null comment '操作的方法名',
method_desc varchar(100) null comment '方法用途',
method_params varchar(1000) null comment '方法参数',
return_value varchar(2000) null comment '返回值',
operate_user int unsigned null comment '操作人ID',
operate_time datetime null comment '操作时间',
cost_time bigint null comment '方法执行耗时, 单位:ms'
)
comment '操作日志表';
2.添加注解
然后在启动类上添加@EnableAspectJAutoProxy注解,开启AOP服务.
3.创建日志类
@Component
@Aspect
public class LogAspect {
@Autowired
private HttpServletRequest request;
@Autowired
private OperateLogMapper operateLogMapper;
//自定义注解
@Pointcut("@annotation(com.itheima.anno.LogAnno)")
public void pt() {
}
//环绕通知
@Around("pt()")
public Object logAround(ProceedingJoinPoint pjp) {
OperateLog operateLog = new OperateLog();
//日志信息包含:方法作用、、返回值、方法执行时长
try {
String token = request.getHeader("token");
Integer id = JwtUtils.parseJWT(token).get("id", Integer.class);
operateLog.setOperateUser(id);//操作人id
} catch (Exception e) {
e.printStackTrace();
}
MethodSignature ms = (MethodSignature) pjp.getSignature();
operateLog.setMethodName(ms.getMethod().getName());//方法名
operateLog.setMethodDesc(ms.getMethod().getAnnotation(LogAnno.class).methodDesc());//方法作用
operateLog.setOperateTime(LocalDateTime.now());//操作时间
operateLog.setClassName(pjp.getTarget().getClass().getName());//全类名
operateLog.setMethodParams(Arrays.toString(pjp.getArgs()));//参数
Object obj = null;
long start = new Date().getTime();
try {
obj = pjp.proceed();
operateLog.setReturnValue(obj.toString());
return obj;
} catch (Throwable e) {
throw new RuntimeException(e);
} finally {
long end = new Date().getTime();
operateLog.setCostTime(end - start);//方法执行时长
operateLogMapper.insert(operateLog);//保存日志
}
}
}
4.创建自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogAnno {
String methodDesc() default "";//方法作用
}
5.将注解加到自己想要测试的类中,例如
@LogAnno(methodDesc = "分页功能")
@GetMapping("/emps")
public Result findByPage(String name, String gender,
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end,
@RequestParam(defaultValue = "1", name = "page") int index,
@RequestParam(defaultValue = "10", name = "pageSize") int page) {
PageBean byPage = empService.findByPage(name, gender, begin, end, index, page);
return Result.success(byPage);
}
就可以记录该方法的执行时间了
另一种切点表达式
当需要测试的方法过多时,添加注解就不是一种合适的处理方式,我们可以通过@Pointcut指定一片区域来批量测试.在@Pointcut表达式中*指1或多个值,
..指0或多个值可以利用表达式指定一个范围内的所有方法
例如:
@Pointcut("execution(* com.itheima.controller.StudentController.*(..))")