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()); } }