注解&AOP打印日志
前言
为了在项目开发时,报错是常出现的事。而我们一般可以通过日志来快速定位问题所在。
这里使用注解&AOP
来实现日志输出。
环境:SpringBoot 2.4.13
实现
- 引入AOP依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
- 声明注解
@Target(ElementType.METHOD) //只能写在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {
String operator() default ""; //方法操作描述
}
- 使用AOP
@Component
@Aspect //切面 定义了通知和切点的关系
@Slf4j
public class LogAspect {
@Pointcut("@annotation(top.wl.blog.annotation.LogAnnotation)")
public void pt(){}
//环绕通知
@Around("pt()")
public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
String methodName = method.getName();
log.info("====================={}() start================================",methodName);
log.info("operation:{}",logAnnotation.operator());
//请求的方法名
String className = joinPoint.getTarget().getClass().getName();
log.info("request method:{}",className + "." + methodName + "()");
// //请求的参数
Object[] args = joinPoint.getArgs();
if (args.length != 0){
String params = Arrays.toString(args);
log.info("params:{}",params);
}
long beginTime = System.currentTimeMillis();
Object result = null;
try {
//执行方法
result = joinPoint.proceed();
} catch (Exception e) {
log.error("Exception{},Msg:{}",e.getClass(),e.getMessage());
throw new RuntimeException(e.getMessage());
} finally {
//执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日志
log.info("execute time : {} ms",time);
log.info("====================={}() end================================",methodName);
}
return result;
}
}
- 使用注解
@GetMapping("/list")
@LogAnnotation(operator = "用户列表") //日志注解
public R getList(@RequestParam String key){
List<SysUser> list = userService.getList(key);
//int a = 10/0; //测试异常情况
return R.success(list);
}
- 扩展
需要将日志保存到数据库,可以在AOP的环绕通知里设置