介绍:
很多时候会需要提供一些统计记录的,比如某个服务一个月的被调用量、接口的调用次数、成功调用次数等等。
优点:
使用AOP+Hendler对业务逻辑代码无侵入,完全解耦。通过spring boot自带的健康检查接口(/health)方便、安全。
注意:
数据没有被持久化,只保存在内存中,重启后数据将被重置。可按需自己实现
代码:
AOP:在AOP中调用Handler
@Component @Aspect public class ControllerAdvice { private static ILogger log = LoggerFactory.getLogger(ControllerAdvice.class); @Around("execution(public * *..*controller.*.*(..))") public Object handle(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { Object result; try { Function<ProceedingJoinPoint, AbstractControllerHandler> build = AbstractControllerHandler.getBuild(); if (null == build) { AbstractControllerHandler.registerBuildFunction(DefaultControllerHandler::new); } build = AbstractControllerHandler.getBuild(); AbstractControllerHandler controllerHandler = build.apply(proceedingJoinPoint); if (null == controllerHandler) { log.warn(String.format("The method(%s) do not be handle by controller handler.", proceedingJoinPoint.getSignature().getName())); result = proceedingJoinPoint.proceed(); } else { result = controllerHandler.handle(); } } catch (Throwable throwable) { RuntimeHealthIndicator.failedRequestCount++; log.error(new Exception(throwable), "Unknown exception- -!"); throw throwable; } return result; } }
Handler:执行记录的逻辑
抽象类:AbstractControllerHandler
public abstract class AbstractControllerHandler { private static ILogger log = LoggerFactory.getLogger(AbstractControllerHandler.class); private static Function<ProceedingJoinPoint, AbstractControllerHandler> build; public static Function<ProceedingJoinPoint, AbstractControllerHandler> getBuild() { return build; } public static void registerBuildFunction(Function<ProceedingJoinPoint, AbstractControllerHandler> build) { Assert.isNotNull(build, "build"); AbstractControllerHandler.build = build; } protected ProceedingJoinPoint proceedingJoinPoint; protected HttpServletRequest httpServletRequest; protected String methodName; protected String uri; protected String requestBody; protected String ip; protected Method method; protected boolean inDataMasking; protected boolean outDataMasking; public AbstractControllerHandler(ProceedingJoinPoint proceedingJoinPoint) { Assert.isNotNull(proceedingJoinPoint, "proceedingJoinPoint"); this.proceedingJoinPoint = proceedingJoinPoint; Signature signature = this.proceedingJoinPoint.getSignature(); this.httpServletRequest = this.getHttpServletRequest(this.proceedingJoinPoint.getArgs()); this.methodName = signature.getName(); this.uri = null == this.httpServletRequest ? null : this