java实现日志aop切面 和业务功能进行解耦

背景

在之前的项目中,每次想加调试日志,或者打印请求的时候都需要在类上增加一句

private static Logger log = LoggerFactory.getLogger(xxx.class);

后面写多了之后总觉得很麻烦的,就想能不能使用aop切面的方式来增加日志。废话不多说,开干。

引入版本

         <!--aop-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        
       

自定义注解

/**
 * 接受外来服务请求的日志注解
 * 记录请求和对应的返回值
 *
 * @author dzp
 * @since 2020/9/2
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface RequestLog {
    /**
     * 是否记录请求参数
     */
    boolean logParameters() default true;

    /**
     * 是否记录请求日志
     */
    boolean logRequest() default true;

    /**
     * 是否记录返回值
     */
    boolean logReturn() default false;

    /**
     * 是否以debug形式记录
     */
    boolean isDebug() default false;


    /**
     * 日志类型
     */
    LogNameEnum logName() default LogNameEnum.MEDICAL_APP;
}

日志类型枚举

 /**
 * 日志类型
 *
 * @author dzp
 * @since 2020/12/6
 */
@Getter
public enum LogNameEnum {
    /**
     * 系统日志
     */
    MEDICAL_APP(LoggerFactory.getLogger("medical_app"));


    LogNameEnum(final Logger logger) {
        this.logger = logger;
    }

    private final Logger logger;
}



常量类

public class LogConfig {
    public enum LogType {
        /**
         * 请求日志
         */
        HTTP,

    }


    /**
     * http 请求url和参数
     */
    public static final String HTTP_REQUEST_URL_LOG = "%s ----> " + LogType.HTTP.toString() + " --------> url【%s】param:【%s】";
    /**
     * http 请求url
     */
    public static final String HTTP_REQUEST_URL_PARAM_LOG = "%s ----> " + LogType.HTTP.toString() + " --------> url【%s】";
    /**
     * http 响应
     */
    public static final String HTTP_RESPONSE_RESULT_LOG = "%s ----> " + LogType.HTTP.toString() + " --------> return:【%s】";



}

aop切面

 
/**
 * 用来记录相关日志
 *
 * @author dzp
 * @since 2020/9/2
 */
@Aspect
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestLogAspect {


    @Pointcut("within(@com.medical.app.aop.annotations.RequestLog *)")
    public void withRequestLogAnnotation() {
    }

    @Around("withRequestLogAnnotation()")
    public Object requestLogHandle(ProceedingJoinPoint pjp) throws Throwable {
        //尝试获取当前方法的类名和方法名
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        RequestLog requestLog = signature.getMethod().getAnnotation(RequestLog.class);
        if (requestLog == null) {
            requestLog = signature.getMethod().getDeclaringClass().getAnnotation(RequestLog.class);
        }
        //对于Web项目我们可以从上下文中获取到额外的一些信息来丰富我们的日志
        String url = "";
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
            url = request.getRequestURL().toString();
        }
        long timestamp = System.currentTimeMillis();


        //实现的是入参的日志输出
        if (requestLog.logParameters() && requestLog.logRequest()) {
            if (pjp.getArgs() != null && pjp.getArgs().length > 0) {
                Object arg = pjp.getArgs()[0];
                if(arg instanceof MultipartFile) {
                    arg=((MultipartFile) arg).getName();
                }
                if (requestLog.isDebug()) {
                    requestLog.logName().getLogger().debug(String.format(LogConfig.HTTP_REQUEST_URL_LOG,  timestamp, url, JSON.toJSONString(arg)));
                } else {

                    requestLog.logName().getLogger().info(String.format(LogConfig.HTTP_REQUEST_URL_LOG,  timestamp, url,JSON.toJSONString(arg) ));
                }
            }
        } else {
            if (requestLog.logRequest()) {
                if (requestLog.isDebug()) {
                    requestLog.logName().getLogger().debug(String.format(LogConfig.HTTP_REQUEST_URL_PARAM_LOG,  timestamp, url));
                } else {
                    requestLog.logName().getLogger().info(String.format(LogConfig.HTTP_REQUEST_URL_PARAM_LOG,  timestamp, url));
                }
            }
        }

        Object returnValue = pjp.proceed();

        //实现了返回值的日志输出
        if (requestLog.logReturn()) {
            if (requestLog.isDebug()) {
                requestLog.logName().getLogger().debug(String.format(LogConfig.HTTP_RESPONSE_RESULT_LOG,  timestamp, JSON.toJSONString(returnValue)));
            } else {
                requestLog.logName().getLogger().info(String.format(LogConfig.HTTP_RESPONSE_RESULT_LOG,  timestamp,JSON.toJSONString(returnValue)));
            }
        }

        return returnValue;
    }

}

使用案例

/**
 * @author dzp
 * @since 2019/5/29
 * 测试接口 无任何意义
 */
@RestController
@CrossOrigin(value = "*", maxAge = 3600)
@RequestLog
public class TestController  {

    /**
     * @return
     */
    @RequestMapping("/test")
    public ResponseResult<Object>  test(String msg){
        return ResponseResult.success();
    }


}

启动项目调用该接口:
http://localhost:8888/test?msg=test

成功截图

在这里插入图片描述

学习java群

java交流群:868794080
源码地址

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一枚开发小咸鱼

原创不宜,请作者喝杯咖啡吧。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值