用自定義註解實現接口信息的日誌打印

  • 導入boot項目的aop依賴

     <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-aop</artifactId>
     </dependency>
  • 定義註解

    import java.lang.annotation.*;
    
    /**
     * web日誌註解
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD})
    @Documented
    public @interface WebLog {
    
        /**
         * 日誌描述信息
         *
         * @return
         */
        String description() default "";
    }
  • 註解實現類

    import com.google.gson.Gson;
    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import javax.servlet.http.HttpServletRequest;
    import java.lang.reflect.Method;
    import java.util.Objects;
    
    @Aspect
    @Configuration
    @Slf4j
    public class WebLogAspect {
    
        /**
         * 以自定義@WebLog註解爲切點
         */
        @Pointcut("@annotation(com.experiencetex.skills.config.annotation.WebLog)")
        public void webLog() {
        }
    
        /**
         * 環繞
         *
         * @return java.lang.Object
         * @params [pjp]
         * @description
         */
        @Around("webLog()")
        public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
            long startTime = System.currentTimeMillis();
            Object result = pjp.proceed();
            if (!(result instanceof ResponseEntity)) {
                log.info("Response Args  : {}", new Gson().toJson(result));
                log.info("Time-Consuming : {}", System.currentTimeMillis() - startTime);
            }
    
            return result;
        }
    
    
        /**
         * 在切點以前記錄
         *
         * @return void
         * @params [joinPoint]
         * @description
         */
        @Before("webLog()")
        public void doBefore(JoinPoint joinPoint) throws Exception {
            // 開始打印請求日誌
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
            // 獲取 @WebLog 註解的描述信息
            String methodDescription = getAspectLogDescription(joinPoint);
            // 打印請求相關參數
            log.info("======================================== Start ==========================================");
            // 打印請求 url
            log.info("URL            : {}", request.getRequestURL().toString());
            // 打印描述信息
            log.info("Description    : {}", methodDescription);
            // 打印 Http method
            log.info("HTTP Method    : {}", request.getMethod());
            // 打印調用 controller 的全路徑以及執行方法
            log.info("Class Method   : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
            // 打印請求的 IP
            log.info("IP             : {}", request.getRemoteAddr());
            // 打印請求入參
            log.info("Request Args   : {}", new Gson().toJson(joinPoint.getArgs()));
        }
    
        /**
         * 獲取切面註解的描述
         *
         * @param joinPoint 切點
         * @return 描述信息
         * @throws Exception
         */
        public String getAspectLogDescription(JoinPoint joinPoint) throws Exception {
            String targetName = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            Object[] arguments = joinPoint.getArgs();
            Class targetClass = Class.forName(targetName);
            Method[] methods = targetClass.getMethods();
            StringBuilder description = new StringBuilder();
            for (Method method : methods) {
                if (method.getName().equals(methodName)) {
                    Class[] clazzs = method.getParameterTypes();
                    if (clazzs.length == arguments.length) {
                        description.append(method.getAnnotation(WebLog.class).description());
                        break;
                    }
                }
            }
            return description.toString();
        }
    }
相關文章
相關標籤/搜索