自定义注解实现AOP切面日志操作

  • 介绍

最近自己在做项目时,因为要使用到日志记录功能,故翻阅之前自己的学习文章,从新理解并加以总结后加入自己的项目中,对此相关的一些技术知识点做一些分享。

  • 环境

java:11
maven:3.8.1
springboot:2.6.6

注意:如若不熟悉AOP以及注解如何使用请先通过下文了解先。

java注解快速入门


  • 添加依赖
<!-- 添加所需依赖 -->
<dependencies>
    <!--fastjson-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
    </dependency>
    <!--aop-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
</dependencies>

  • 自定义日志注解LogAnnotation.java

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {

    // 设置所需参数以及默认值
    String module() default "";

    String operate() default "";

}

  • 自定义日志切面类LogAspect.java

@Component
@Aspect
@Slf4j
public class LogAspect {

    /**
     * 切点
     * 注意:这里的路径最好写全路径 不写全有时会有错误
     *
     * 参数说明:
     * 使用@annotation时,所修饰的方法或是接口都会被拦截。
     * 使用execution时,指定你要切入的一个地方。
     */
    //@Pointcut("@annotation(LogAnnotation)")
    @Pointcut("@annotation(com.hetongxue.aop.log.LogAnnotation)")
    public void pointcut() {
    }

    /**
     * 通知
     * 注意:对应上面得切点方法名称
     */
    @Around("pointcut()")
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        // 记录开始时长
        long beginTime = System.currentTimeMillis();
        // 执行方法
        Object result = joinPoint.proceed();
        // 执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        // 记录日志
        recordLog(joinPoint, time);
        return result;
    }

    /**
     * 记录日志
     */
    private void recordLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
        log.info("===============================日志开始===============================");
        log.info("日志模块:{}", logAnnotation.module());
        log.info("日志操作:{}", logAnnotation.operate());
        log.info("请求方法:{}", joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()");
        log.info("请求参数:{}", JSON.toJSONString(joinPoint.getArgs()[0]));
        log.info("请求时长:{} ms", time);
        log.info("请求IP:{}", getRequestIp());
        log.info("===============================日志结束===============================");
    }

    /**
     * 获取请求IP地址
     */
    private String getRequestIp() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        assert requestAttributes != null;
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        assert request != null;
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}

  • 使用TestController.java测试

@RestController
public class TestController {

    @GetMapping("/test")
    @LogAnnotation(module = "测试", operate = "测试使用")
    public String test(@RequestParam String name) {
        return Result.Success().setMessage("你好," + name + "!");
    }

}

  • 日志结果
2022-07-05 20:53:11.689  INFO 15548 --- [nio-8080-exec-1] com.hetongxue.aop.log.LogAspect          : 日志模块:测试
2022-07-05 20:53:11.689  INFO 15548 --- [nio-8080-exec-1] com.hetongxue.aop.log.LogAspect          : 日志操作:测试使用
2022-07-05 20:53:11.689  INFO 15548 --- [nio-8080-exec-1] com.hetongxue.aop.log.LogAspect          : 请求方法:com.hetongxue.system.controller.TestController.test()
2022-07-05 20:53:11.703  INFO 15548 --- [nio-8080-exec-1] com.hetongxue.aop.log.LogAspect          : 请求参数:["何同学"]
2022-07-05 20:53:11.703  INFO 15548 --- [nio-8080-exec-1] com.hetongxue.aop.log.LogAspect          : 请求时长:3 ms
2022-07-05 20:53:11.703  INFO 15548 --- [nio-8080-exec-1] com.hetongxue.aop.log.LogAspect          : 请求IP:127.0.0.1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_何同学

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值