介绍:
很多时候会需要提供一些统计记录的,比如某个服务一个月的被调用量、接口的调用次数、成功调用次数等等。
优点:
使用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