Springboot AOP实现接口访问次数统计
参考链接:点击
1、引入依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.12</version>
</dependency>
2、aop依赖
@Component
@Aspect
public class ApiVisitHistory {
private Logger log = LoggerFactory.getLogger(ApiVisitHistory.class);
ThreadLocal<Long> startTime = new ThreadLocal<>();
/**
* 定义切面
* - 此处代表com.smile.demo.controller包下的所有接口都会被统计
*/
@Pointcut("execution(* com.smile.demo.controller..*.*(..))")
public void pointCut(){
}
/**
* 在接口原有的方法执行前,将会首先执行此处的代码
*/
@Before("pointCut()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
startTime.set(System.currentTimeMillis());
//获取传入目标方法的参数
Object[] args = joinPoint.getArgs();
log.info("类名:{}", joinPoint.getSignature().getDeclaringType().getSimpleName());
log.info("方法名:{}", joinPoint.getSignature().getName() );
}
/**
* 只有正常返回才会执行此方法
* 如果程序执行失败,则不执行此方法
*/
@AfterReturning(returning = "returnVal", pointcut = "pointCut()")
public void doAfterReturning(JoinPoint joinPoint, Object returnVal) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 执行成功则计数加一
AtomicCounter.getInstance().increase();
log.info("URI:[{}], 耗费时间:[{}] ms, 访问次数:{}", request.getRequestURI(), System.currentTimeMillis() - startTime.get(), AtomicCounter.getInstance().getValue());
}
/**
* 当接口报错时执行此方法
*/
@AfterThrowing(pointcut = "pointCut()")
public void doAfterThrowing(JoinPoint joinPoint) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
log.info("接口访问失败,URI:[{}], 耗费时间:[{}] ms", request.getRequestURI(), System.currentTimeMillis() - startTime.get());
}
}
3、controller层代码
@RestController
@RequestMapping("/api/test")
public class HelloController {
/**
* 获取字符串
* @return
*/
@ResponseBody
@RequestMapping("/getString")
public String getString(){
return "这是一条字符串";
}
/**
* 模拟错误访问
* @return
*/
@ResponseBody
@RequestMapping("/testToError")
public String testToError() throws Exception{
try {
Integer.parseInt("slfda");
return "success";
}catch (Exception e){
throw e;
}
}
}
4、AtomicCounter代码
import java.util.concurrent.atomic.AtomicInteger;
/**
* 计数器,统计当前执行的任务数
* @author gh
* @date 2020/12/25
*/
public class AtomicCounter {
private static final AtomicCounter atomicCounter = new AtomicCounter();
/**
* 单例,不允许外界主动实例化
*/
private AtomicCounter() {
}
public static AtomicCounter getInstance() {
return atomicCounter;
}
private static AtomicInteger counter = new AtomicInteger();
public int getValue() {
return counter.get();
}
public int increase() {
return counter.incrementAndGet();
}
public int decrease() {
return counter.decrementAndGet();
}
// 清零
public void toZero(){
counter.set(0);
}
}
如果觉得有用,各位观众老爷点个赞再走哈~谢谢(其实再加个关注也不介意哈哈哈)