赞
踩
@Aspect 切面类
@Before 前置
@AfterReturning 后置
@Around 环绕
@AfterThrowing 异常
execution(public * *(..)) 定义任意公共方法的执行
execution(* set*(..)) 定义任何一个以"set"开始的方法的执行
execution(* com.sys.service.UserService.*(..)) 定义UserService 接口的任意方法的执行
execution(* com.sys.service.*.*(..)) 定义在service包里的任意方法的执行
execution(* com.sys.service ..*.*(..)) 定义在service包和所有子包里的任意类的任意方法的执行
execution(* com.sys.pointcutexp…JoinPointObject.*(…)) 定义在pointcutexp包和所有子包里的JoinPointObject类的任意方法的执行
使用@AfterReturning方法拿到请求接口的返回状态码,将需要处理的问题状态码及错误信息保存到数据库及输出到日志文件,方便通过数据库进行接口调用错误信息监控。通过配置切入点对controller的所有请求接口进行处理,就无需再在每一个请求方法中进行处理。
使用@AfterThrowing方法拿到请求接口方法异常调用信息,其他同上。
package com.system.common.aop; import com.alibaba.fastjson.JSON; import com.system.service.SysLogService; import com.xlx.entity.BaseResponse; import com.xlx.entity.bsc.system.DO.SystemLogInfoDO; import com.xlx.utils.ExceptionUtil; import com.xlx.utils.StringParseUtils; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.lang.reflect.Method; import java.util.Arrays; /** * @version: java version 1.8 * @Author: sagitario * @description: 异常请求记录到数据库及日志输出 * @date: 2023-04-20 11:44 */ @Component @Aspect @Slf4j public class ApiResponseAOP { @Autowired private SysLogService sysLogService; private static String [] passUrl = {"过滤的请求url"}; @Pointcut("execution(* com.*.controller.*.*(..))") private void methodAspect(){}//定义一个切入点 @Before("methodAspect()") public void doAudit(JoinPoint joinPoint) { log.info("BeforeAdvice............."); } @AfterReturning(value = "methodAspect()",returning = "methodResult") public void afterReturning(JoinPoint joinPoint, Object methodResult) { MethodSignature ms = (MethodSignature) joinPoint.getSignature(); Method method = ms.getMethod(); String clazz = method.getDeclaringClass().getName(); log.debug("请求类为:" + clazz); String mName = method.getName(); log.debug("请求方法为:" + mName); if(Arrays.binarySearch(passUrl, mName)<0){ BaseResponse baseResponse = (BaseResponse) methodResult; if(!baseResponse.isSuccess()){ StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < joinPoint.getArgs().length; i++) { log.debug("请求参数为:" + JSON.toJSONString(joinPoint.getArgs()[i])); stringBuffer.append(JSON.toJSONString(joinPoint.getArgs()[i])); } log.debug("请求返回内容为:" + methodResult.toString()); SystemLogInfoDO systemLogInfoDO = new SystemLogInfoDO(); systemLogInfoDO.setInfo(clazz + "." + mName); systemLogInfoDO.setParam(stringBuffer.toString()); systemLogInfoDO.setCode(baseResponse.getCode()); systemLogInfoDO.setMessage(baseResponse.getMessage()); if(baseResponse.getCode()==204){ systemLogInfoDO.setLevel("INFO"); }else{ systemLogInfoDO.setLevel("ERROR"); } sysLogService.insertSelective(systemLogInfoDO); } } } @AfterThrowing(value = "methodAspect()",throwing = "e") public void afterThrowing(JoinPoint joinPoint, Exception e) { log.info("AfterThrowing advice"); MethodSignature ms = (MethodSignature) joinPoint.getSignature(); Method method = ms.getMethod(); String clazz = method.getDeclaringClass().getName(); log.info("请求类为:" + clazz); String mName = method.getName(); log.info("请求方法为:" + mName); SystemLogInfoDO systemLogInfoDO = new SystemLogInfoDO(); try { StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < joinPoint.getArgs().length; i++) { log.info("请求参数为:" + JSON.toJSONString(joinPoint.getArgs()[i])); stringBuffer.append(JSON.toJSONString(joinPoint.getArgs()[i])); } systemLogInfoDO.setParam(stringBuffer.toString()); }catch (Exception e1){ log.info("请求方法参数无法解析:" + ExceptionUtil.getMessage(e1)); systemLogInfoDO.setParam("请求方法参数无法解析"); } String error = ExceptionUtil.getMessage(e); log.info("afterThrowing异常:{}",error); systemLogInfoDO.setInfo(clazz + "." + mName); systemLogInfoDO.setCode(500); systemLogInfoDO.setMessage(error); systemLogInfoDO.setLevel("EXCEPTION"); sysLogService.insertSelective(systemLogInfoDO); } }
2023-05-22 18:36:14 [http-nio-8831-exec-6] [com.loan.common.aop.ApiResponseAOP:82] INFO com.loan.common.aop.ApiResponseAOP - 请求类为:com.loan.controller.RepayController
2023-05-22 18:36:14 [http-nio-8831-exec-6] [com.loan.common.aop.ApiResponseAOP:84] INFO com.loan.common.aop.ApiResponseAOP - 请求方法为:repaymentRecord
2023-05-22 18:36:14 [http-nio-8831-exec-6] [com.loan.common.aop.ApiResponseAOP:89] INFO com.loan.common.aop.ApiResponseAOP - 请求参数为:"110014"
2023-05-22 18:36:14 [http-nio-8831-exec-6] [com.xlx.exception.GlobalExceptionHandler:26] ERROR com.xlx.exception.GlobalExceptionHandler - feign.RetryableException: Read timed out executing GET http://external-platform-server/repay/repaymentRecords
at feign.FeignException.errorExecuting(FeignException.java:213)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:115)
......
2023-05-22 18:36:14 [http-nio-8831-exec-6] [com.loan.common.aop.ApiResponseAOP:98] INFO com.loan.common.aop.ApiResponseAOP - afterThrowing异常:feign.RetryableException: Read timed out executing GET http://external-platform-server/repay/repaymentRecordsat feign.FeignException.errorExecuting(FeignException.java:213)at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:115)at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:80)at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
JDK动态代理相关可参考 一篇文章彻底搞懂java AOP、@Before、@After、@AfterReturning、@AfterThrowing、@Around的使用、Spring AOP详解
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。