1. 程式人生 > 其它 >AOP併發情況下列印請求資訊

AOP併發情況下列印請求資訊

AOP列印引數在併發情況下會出現請求資訊執行緒序列的問題,經改造如下:

package com.example.aspect;

import com.alibaba.fastjson2.JSON;
import com.pacific.external.callback.util.CurrentContextUtils;
import org.apache.commons.lang.ArrayUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; /** * ClassName HttpAspect * * @Description AOP 日誌列印 * @Author mingtian * @Date 2022/5/13 13:18 * @Version 1.0 */ @Aspect @Component public class HttpAspect { /** * 列印日誌
*/ protected Logger logger = LoggerFactory.getLogger(HttpAspect.class); /** * 跨行 */ private static final String LINE_SEPARATOR = System.lineSeparator(); /** * 要處理的方法,包名+類名+方法名 */ @Pointcut("execution(* com.example.controller..*.*(..))") public void cut() { } /** * //在呼叫上面 @Pointcut標註的方法前執行以下方法 * * @param joinPoint */ @Before("cut()") public void doBefore(JoinPoint joinPoint) { logger.info("------------------------ Start ----------------------------"); HttpServletRequest request = CurrentContextUtils.getCurrentRequestInfo(); Signature signature = joinPoint.getSignature(); StringBuilder requestInfo = new StringBuilder(32); // 列印請求引數 requestInfo.append(LINE_SEPARATOR); requestInfo.append("Request MethodType:").append(request.getMethod()).append(LINE_SEPARATOR); requestInfo.append("Request IP:").append(request.getRemoteAddr()).append(LINE_SEPARATOR); requestInfo.append("Request Url:").append(request.getRequestURL().toString()).append(LINE_SEPARATOR); requestInfo.append("Request Class.Methods:").append(signature.getDeclaringTypeName()).append(".").append(signature.getName()).append(LINE_SEPARATOR); Object[] args = joinPoint.getArgs(); // 序列化時過濾掉request和response List<Object> logArgs = streamOf(args).filter(arg -> (!(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse))) .collect(Collectors.toList()); String argStr = JSON.toJSONString(logArgs); requestInfo.append("Request Param:").append(argStr).append(LINE_SEPARATOR); logger.info("requestInfo:{}", requestInfo); } /** * 判斷引數型別是否是檔案 * * @param signature * @return */ public boolean checkParamType(Signature signature) { MethodSignature methodSignature = (MethodSignature) signature; Class<?>[] parameterTypes = methodSignature.getParameterTypes(); logger.info("parameterTypes:{}", (Object) parameterTypes); for (Class<?> cla : parameterTypes) { if (isFile(cla)) { return true; } } return false; } /** * 過濾工具類 * * @param array * @param <T> * @return */ public static <T> Stream<T> streamOf(T[] array) { return ArrayUtils.isEmpty(array) ? Stream.empty() : Arrays.stream(array); } /** * 呼叫方法以何種方式結束,都會執行 */ @After("cut()") public void doAfter() { } /** * //在呼叫上面 @Pointcut標註的方法後執行。用於獲取返回值 * * @param obj */ @AfterReturning(returning = "obj", pointcut = "cut()") public void doAfterReturning(Object obj) { logger.info("Response Result:{}", JSON.toJSONString(obj)); logger.info("------------------------ End ----------------------------" + LINE_SEPARATOR); } /** * 檔案上傳欄位不列印 * * @param clazz * @return */ private boolean isFile(Class<?> clazz) { if (MultipartFile.class.isAssignableFrom(clazz)) { return true; } return (clazz.isArray()) && (MultipartFile.class.isAssignableFrom(clazz.getComponentType())); } }

 獲取當前執行緒工具類:

package com.example.util;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Description: CurrentContextUtils  獲取當前執行緒方法
 * @Author: mingtian
 * @CreateDate: 2022/5/13 13:12
 * @Version: 1.0
 */
public class CurrentContextUtils {

    /**
     * 返回當前執行緒上下文request資訊
     *
     * @return
     */
    public static HttpServletRequest getCurrentRequestInfo() {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return servletRequestAttributes.getRequest();
    }

    /**
     * 返回當前執行緒上下文response資訊
     *
     * @return
     */
    public static HttpServletResponse getCurrentResponseInfo() {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return servletRequestAttributes.getResponse();
    }
}