AOP

AOP

依赖:

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

第一种方式:

package com.atguigu.activity.aop;
​
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
​
import java.util.Objects;
​
/**
 * @author : lijiexi
 * @class : LogAOP
 * @date : 2023/7
 */
​
@Slf4j
@Aspect
@Component
public class LogAOP {
    /**
     * 手动创建的对象所在包
     */
    public static final String PACKAGE_NAME = "com.cfl.jd";
​
    /**
     * 全局日志输出
     * @param pjp
     * @return
     * @throws Throwable
     */
    //切入点,导入controller文件路劲
    @Around(value = "execution(* com.atguigu.activity.controller.*.*(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        // 参数值
        Object[] args = pjp.getArgs();
        Signature signature = pjp.getSignature();
        // 完全方法名(完全类名+方法名)
        String entirelyMethodName = signature.getDeclaringTypeName() + "." + signature.getName();
        // 参数名
        MethodSignature methodSignature = (MethodSignature) signature;
        String[] parameterNames = methodSignature.getParameterNames();
        Class[] parameterTypes = methodSignature.getParameterTypes();
        // 方法返回值
//        String returnTypeName = methodSignature.getReturnType().getName();
        StringBuilder sb = new StringBuilder();
        for (int i = 0, length = args.length; i < length; i++) {
            sb.append("参数:").append(parameterNames[i]).append("(").append(parameterTypes[i].getName()).append(")")
                    .append(" ————> ");
            if (Objects.nonNull(args[i])) {
                if (parameterTypes[i].getName().indexOf(LogAOP.PACKAGE_NAME) != -1) {
                    sb.append(JSON.toJSONString(args[i]));
                } else{
                    sb.append(args[i].toString());
                }
            } else {
                sb.append("null");
            }
​
            if (i < length - 1) {
                sb.append("\n");
            }
​
        }
        if (args.length > 0) {
            log.info("方法:{} 开始执行,请求参数如下:\n{}",entirelyMethodName, sb.toString());
        }
​
        // 继续执行方法
        Object obj = pjp.proceed();
​
        if (Objects.nonNull(obj)) {
            String name = obj.getClass().getName();
            if (name.indexOf(LogAOP.PACKAGE_NAME) != -1) {
                log.info("方法:{} 结束执行,返回值:\n{}", entirelyMethodName, JSON.toJSONString(obj));
            } else {
                log.info("方法:{} 结束执行,返回值:\n{}", entirelyMethodName, obj.toString());
            }
        }
​
        return obj;
    }
​
}
​

第二种方式:

package com.atguigu.service.aop;
​
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
​
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;
​
/**
 * @author : lijiexi
 * @class : WebLogAspect
 * @date : 2023/7/22
 */
​
@Aspect
@Component
@Slf4j
public class WebLogAspect {
​
    /**
     * 进入方法时间戳
     */
    private Long startTime;
    /**
     * 方法结束时间戳(计时)
     */
    private Long endTime;
​
    public WebLogAspect() {
    }
​
​
    /**
     * 定义请求日志切入点,其切入点表达式有多种匹配方式,这里是指定路径
     */
    //切点
    @Pointcut("execution(public * com.atguigu.service.product.controller.*.*(..))")
    public void webLogPointcut() {
    }
​
    /**
     * 前置通知:
     * 1. 在执行目标方法之前执行,比如请求接口之前的登录验证;
     * 2. 在前置通知中设置请求日志信息,如开始时间,请求参数,注解内容等
     *
     * @param joinPoint
     * @throws Throwable
     */
    @Before("webLogPointcut()")
    public void doBefore(JoinPoint joinPoint) {
​
        // 接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //打印请求的内容
        startTime = System.currentTimeMillis();
        System.out.println("<==========================================="+request.getMethod()+"============================================>");
        log.info("请求开始时间:" + LocalDateTime.now());
        log.info("请求Url : " + request.getRequestURL().toString());
       // log.info("请求方式 : " + request.getMethod());
        log.info("请求ip : " + request.getRemoteAddr());
        log.info("请求方法 : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        log.info("请求参数 : " + Arrays.toString(joinPoint.getArgs()));
    }
​
    /**
     * 返回通知:
     * 1. 在目标方法正常结束之后执行
     * 1. 在返回通知中补充请求日志信息,如返回时间,方法耗时,返回值,并且保存日志信息
     *
     * @param ret
     * @throws Throwable
     */
    @AfterReturning(returning = "ret", pointcut = "webLogPointcut()")
    public void doAfterReturning(Object ret) throws Throwable {
        endTime = System.currentTimeMillis();
        log.info("请求结束时间:" + LocalDateTime.now());
        log.info("请求耗时:" + (endTime - startTime));
        // 处理完请求,返回内容
        log.info("请求返回 : " + ret);
    }
​
    /**
     * 异常通知:
     * 1. 在目标方法非正常结束,发生异常或者抛出异常时执行
     * 1. 在异常通知中设置异常信息,并将其保存
     *
     * @param throwable
     */
    @AfterThrowing(value = "webLogPointcut()", throwing = "throwable")
    public void doAfterThrowing(Throwable throwable) {
        // 保存异常日志记录
        log.error("发生异常时间:" + LocalDateTime.now());
        log.error("抛出异常:" + throwable.getMessage());
    }
}
​

 

 
posted @ 2023-07-22 13:30  jessi呀  阅读(20)  评论(0编辑  收藏  举报