1.导入jar包
加入该包后,spring boot默认就会开启aop了。
<!--aop-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.配置yml文件
强制使用cglib进行动态代理,默认使用的是Java的动态代理。
spring:
aop:
#使用cglib进行代理
proxy-target-class: true
3.编写AOP切面
@Aspect
@Component
public class ControllerRequestAdvice {
private static final ThreadLocal<Long> timeThreadLocal = new ThreadLocal<Long>();
public static final Logger logger = LoggerFactory.getLogger(ControllerRequestAdvice.class);
/**
* 定义切点
*/
@Pointcut("execution(public * per.mx.xxx.controller.*.*(..))")
public void log() {
}
/**
* 处理请求前处理
*
* @param joinPoint 连接点
*/
@Before("log()")
public void doBefore(JoinPoint joinPoint) {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
String[] parameterNames = methodSignature.getParameterNames();
Object[] args = joinPoint.getArgs();
String client = request.getRemoteAddr();
String method = request.getMethod();
String requestURI = request.getRequestURI();
String token = request.getHeader("token");
long currentTimeMillis = System.currentTimeMillis();
timeThreadLocal.set(currentTimeMillis);
Map<String, Object> params = new HashMap<>();
for (int i = 0; i < parameterNames.length; i++) {
String parameterName = parameterNames[i];
Object parameterValue = args[i];
if (parameterValue instanceof MultipartFile) {
Map<String, Object> f = getFileParam((MultipartFile) parameterValue);
params.put(parameterName, f);
continue;
}
params.put(parameterName, parameterValue);
}
StringBuffer sb = new StringBuffer();
sb.append("Request_").append(currentTimeMillis).append(" ");
sb.append("<").append(client).append(">");
sb.append(" ").append(method).append(" ");
sb.append("\"").append(requestURI).append("\"");
sb.append(" token:").append(token).append(" ");
sb.append("params").append("=>").append(JSON.toJSONString(params));
logger.info(sb.toString());
}
/**
* 处理请求后返回
*
* @param obj 返回值
*/
@AfterReturning(pointcut = "log()", returning = "obj")
public void afterReturning(Object obj) {
logger.info("Response_" + timeThreadLocal.get() + " => " + JSON.toJSONString(obj));
}
private Map<String, Object> getFileParam(MultipartFile file) {
Map<String, Object> params = new HashMap<>();
params.put("文件名", file.getOriginalFilename());
params.put("文件类型", file.getContentType());
params.put("文件大小", FileUtil.getFileSize(file.getSize()));
return params;
}
}
4、日志切面的优化
@Aspect
@Component
public class ControllerRequestAdvice {
private static final ThreadLocal<Long> timeThreadLocal = new ThreadLocal<Long>();
public static final Logger logger = LoggerFactory.getLogger(ControllerRequestAdvice.class);
/**
* 定义切点
*/
@Pointcut("execution(public * per.mx.xx.controller.*.*(..))")
public void log() {
}
/**
* 处理请求前处理
*
* @param joinPoint 连接点
*/
@Before("log()")
public void doBefore(JoinPoint joinPoint) {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
String[] parameterNames = methodSignature.getParameterNames();
Object[] args = joinPoint.getArgs();
String client = request.getRemoteAddr();
String method = request.getMethod();
String requestURI = request.getRequestURI();
String token = request.getHeader("token");
long currentTimeMillis = System.currentTimeMillis();
timeThreadLocal.set(currentTimeMillis);
Map<String, Object> params = new HashMap<>();
for (int i = 0; i < parameterNames.length; i++) {
String parameterName = parameterNames[i];
Object parameterValue = args[i];
if (parameterValue instanceof MultipartFile) {
Map<String, Object> f = getFileParam((MultipartFile) parameterValue);
params.put(parameterName, f);
continue;
}
params.put(parameterName, parameterValue);
}
StringBuffer sb = new StringBuffer();
sb.append("Request_").append(currentTimeMillis).append(" ");
sb.append("<").append(client).append(">");
sb.append(" ").append(method).append(" ");
sb.append("\"").append(requestURI).append("\"");
sb.append(" token:").append(token).append(" ");
sb.append("params").append("=>").append(JSON.toJSONString(params));
logger.info(sb.toString());
}
/**
* 处理请求后返回
*
* @param obj 返回值
*/
@AfterReturning(pointcut = "log()", returning = "obj")
public void afterReturning(Object obj) {
logger.info("Response_" + timeThreadLocal.get() + " => " + JSON.toJSONString(obj));
}
private Map<String, Object> getFileParam(MultipartFile file) {
Map<String, Object> params = new HashMap<>();
params.put("文件名", file.getOriginalFilename());
params.put("文件类型", file.getContentType());
params.put("文件大小", FileUtil.getFileSize(file.getSize()));
return params;
}
}