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

1. 依赖

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

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;

/**
 * @author : jiangBeiPing
 * @description: 日志切面
 * @date 2021/11/16
 */
@Aspect
@Component
@Slf4j
public class LogAcpect {

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

    }

    /**
     * 方法执行前日志打印
     *
     *      JoinPoint:
     *              --Object[] getArgs:返回目标方法的参数
     *              --Signature getSignature:返回目标方法的签名
     *              --Object getTarget:返回被织入增强处理的目标对象
     *              --Object getThis:返回AOP框架为目标对象生成的代理对象
     * @param joinPoint 织入增强处理的连接点
     */
    @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,无法确定执行顺序。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值