【工作记录】springboot集成aop实现日志@20230918

springboot集成aop实现日志

1. 添加依赖

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

2. 定义注解

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

    String action() default "";

    String topic() default "";

}

3. 定义切面类

import com.cnhqd.authcenter.framework.common.utils.IpUtils;
import com.cnhqd.authcenter.framework.common.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@Aspect
@Component
public class ActionLogAspect {

  @Pointcut("@annotation(com.cnhqd.authcenter.framework.common.log.ActionLog)")
  public void actionLog() {

  }

  /*** 在切点之前织入* @param joinPoint* @throws Throwable*/
  @Before("actionLog()")
  public void doBefore(JoinPoint joinPoint) throws Exception {
    // 开始打印请求日志
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();// 打印请求相关参数
    log.info("=================== Start ====================");
    // 打印请求url
    log.info("URL            : {}", request.getRequestURL().toString());
    // 打印Httpmethod
    log.info("HTTP Method    : {}", request.getMethod());
    // 打印调用 controller 的全路径以及执行方法
    log.info("Class Method   : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
    // 打印请求的IP
    log.info("IP             : {}", IpUtils.getIpAddr(request));
    // 打印请求入参
    log.info("Request Args   : {}", JsonUtils.toJsonString(joinPoint.getArgs()));
    ActionLog annotation = ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(ActionLog.class);
    log.info("topic          :{}", annotation.topic());
    log.info("action         :{}", annotation.action());
  }

  @AfterReturning("actionLog()")
  public void afterReturning(){
    log.info("result        :{}", 200);
    log.info("=================== End ====================");
  }

  @AfterThrowing(pointcut = "actionLog()", throwing = "ex")
  public void afterThrowing(Throwable ex) {
    log.info("result        :{}", ex.getMessage());
    log.info("=================== End ====================");
  }

}

各注解说明:

@Aspect:声明该类为一个注解类;  

@Pointcut:定义一个切点,后面跟随一个表达式,表达式可以定义为某个 package 下的方法,也可以是自定义注解等;  

@Before: 在切点之前,织入相关代码;  

@After: 在切点之后,织入相关代码;  

@AfterReturning: 在切点返回内容后,织入相关代码,一般用于对返回值做些加工处理的场景;  

@AfterThrowing: 用来处理当织入的代码抛出异常后的逻辑处理;  

@Around: 在切入点前后织入代码,并且可以自由的控制何时执行切点;

4. 简单测试

编写测试controller

import com.cnhqd.authcenter.framework.common.log.ActionLog;
import com.cnhqd.authcenter.system.vo.SysAccountLoginVO;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("testAops")
public class TestAopsController {

    @GetMapping("get")
    @ActionLog(action = "get", topic = "测试AOP")
    public String get(String id) {
        return id;
    }

    @PostMapping("post")
    @ActionLog(action = "post", topic = "测试AOP")
    public String post(@RequestBody SysAccountLoginVO vo) {
        System.out.println(JsonUtils.toJsonString(vo));
        return "success";
    }

    @GetMapping("getEx")
    @ActionLog(action = "getEx", topic = "测试AOP")
    public String getEx() {
        throw new RuntimeException("getEx-这里是异常输出测试");
    }

    @PostMapping("postEx")
    @ActionLog(action = "postEx", topic = "测试AOP")
    public String postEx() {
        throw new RuntimeException("postEx-这里是异常输出测试");
    }
}

使用postman发送对应请求,观察控制台输出
postman-get
console-get
postman-getEx
console-getEx
postman-post
console-post
postman-postEx
console-postEx
可以看到日志可以正常输出,如有必要保存相关数据到数据库即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

泽济天下

你的鼓励是我最大的动力。

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

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

打赏作者

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

抵扣说明:

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

余额充值