AOP实现日志打印
一、日志打印标准格式
log.info("=========Start=========");
log.info("URL :{}", request.getRequestURL());
log.info("BusinessName :{}", systemLog.businessName());
log.info("HTTP Method :{}", request.getMethod());
log.info("Class Method :{}.{}", joinPoint.getSignature().getDeclaringTypeName(), ((MethodSignature) joinPoint.getSignature()).getName());
log.info("IP :{}", request.getRemoteHost());
log.info("Request Args :{}", JSON.toJSONString(joinPoint.getArgs()));
log.info("Response :{}", JSON.toJSONString(proceed));
log.info("=========END=========" + System.lineSeparator());
二、注解定义
哪个接口需要打印日志,就添加打印日志注解
package com.atmae.agriculture.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Author: Mae
* @Date: 2022/3/20
* @Time: 8:59
* @Description:
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SystemLog {
String businessName();
}
三、定义切面类
使用环绕通知,业务执行前后都打印日志!
package com.atmae.agriculture.aspect;
import com.alibaba.fastjson.JSON;
import com.atmae.agriculture.annotation.SystemLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* @Author: Mae
* @Date: 2022/3/20
* @Time: 9:02
* @Description: 切面类
*/
@Component
@Aspect
@Slf4j
public class LogAspect {
@Pointcut("@annotation(com.atmae.agriculture.annotation.SystemLog)")
public void pt() {
}
/**
* 环绕通知
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("pt()")
public Object printLog(ProceedingJoinPoint joinPoint) throws Throwable {
Object proceed = null;
try {
handleBefore(joinPoint);
proceed = joinPoint.proceed();
handleAfter(proceed);
} finally {
//System.lineSeparator():系统换行符
log.info("=========END=========" + System.lineSeparator());
}
return proceed;
}
private void handleBefore(ProceedingJoinPoint joinPoint) {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
//获取被增强方法上的注解对象
SystemLog systemLog = getSystemLog(joinPoint);
log.info("=========Start=========");
log.info("URL :{}", request.getRequestURL());
log.info("BusinessName :{}", systemLog.businessName());
log.info("HTTP Method :{}", request.getMethod());
log.info("Class Method :{}.{}", joinPoint.getSignature().getDeclaringTypeName(), ((MethodSignature) joinPoint.getSignature()).getName());
log.info("IP :{}", request.getRemoteHost());
log.info("Request Args :{}", JSON.toJSONString(joinPoint.getArgs()));
}
private void handleAfter(Object proceed) {
log.info("Response :{}", JSON.toJSONString(proceed));
}
private SystemLog getSystemLog(ProceedingJoinPoint joinPoint) {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
SystemLog systemLog = methodSignature.getMethod().getAnnotation(SystemLog.class);
return systemLog;
}
}
四、使用注解打印日志
@PostMapping("/login")
@SystemLog(businessName = "登录")
public ResponseResult login(@RequestBody User user) {
return userService.login(user);
}
五、看看效果吧