Spring之AOP小结(四)Springboot实现AOP日志记录Demo

Spring之AOP小结(四)Springboot实现AOP日志记录Demo,第1张

Spring之AOP小结(四)Springboot实现AOP日志记录Demo 1. 依赖

        org.springframework.boot
        spring-boot-starter-aop

2. 切面类

重要注解:

  • @Aspect:将一个java类定义为切面类
  • @Pointcut:定义一个切入点,可以是一个规则表达式,比如下例中某个package下的所有函数,也可以是一个注解等
  • @Before:在切入点开始处切入内容
  • @After:在切入点结尾处切入内容
  • @AfterReturning:在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
  • @Around:在切入点前后切入内容,并自己控制何时执行切入点自身的内容
  • @AfterThrowing:用来处理当切入内容部分抛出异常之后的处理逻辑
package com.activiti.aop;

import com.alibaba.fastjson.JSONObject;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
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;


@Aspect
@Component
@Slf4j
public class LogAcpect {

    @Pointcut("execution(public * com.activiti.controller..*.*(..))") // 切点
    public void controllerMethod(){

    }

    
    @Before("controllerMethod()")
    public void logRequestInfo(JoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert requestAttributes != null;
        HttpServletRequest request = requestAttributes.getRequest();
        Signature signature = joinPoint.getSignature();
        StringBuilder requestLog = new StringBuilder();
        requestLog.append("请求URL: ").append(request.getRequestURL()).append("n");
        requestLog.append("请求方式: ").append(request.getMethod()).append("n");
        requestLog.append("请求IP: ").append(request.getRemoteAddr()).append("n");
        requestLog.append("类方法: ").append(signature.getDeclaringTypeName()).append("n");

        // 请求参数
        String[] parameterNames = ((MethodSignature) signature).getParameterNames();
        Object[] parameterValues = joinPoint.getArgs();
        int paramLength = parameterNames == null ? 0 : parameterNames.length;
        if (paramLength == 0){
            requestLog.append("无参请求");
        }else {
            requestLog.append("请求参数 = [");
            for (int i = 0; i < paramLength; i++) {
                requestLog.append(parameterNames[i]).append("=").append(JSONObject.toJSONString(parameterValues[i]));
            }
            requestLog.append("]");
        }
        log.info(requestLog.toString());
    }

    @AfterReturning(returning = "returnValue",pointcut = "controllerMethod()")
    public void logReturnValue(Object returnValue) throws Throwable{
        log.info("方法返回值:{}",returnValue.toString());
    }

}

3. 测试类
 @GetMapping("/aopTest")
    @ResponseBody
    public String aopTest(@RequestParam("name") String name){
        return "success" + name;
    }

4. 测试效果

5. 注意问题
  1. 启动类无需加@EnableAspectJAutoProxy注解,引入了AOP依赖后,默认已经开启。
  2. 不同的@Aspect类依靠@Order(x)注解来区分优先级,order的值越小越先执行。
  3. 同一个@Aspect类,针对同一个 pointcut,定义了两个相同的advice,无法确定执行顺序。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/zaji/5522323.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-13
下一篇2022-12-13

发表评论

登录后才能评论

评论列表(0条)

    保存