Spring Boot如何统计一个Bean中方法的调用次数

目录

实现思路

前置条件

实现步骤

首先我们先自定义一个注解

接下来定义一个切面

需要统计方法上使用该注解

测试


实现思路

通过AOP即可实现,通过AOP对Bean进行代理,在每次执行方法前或者后进行几次计数统计。这个主要就是考虑好如何避免并发情况下不准,以及如何使用AOP实现代理。

前置条件

首先搭建一个spring boot工程,我这里用的是3x版本

搭建步骤:

新版idea创建spring boot项目-CSDN博客https://blog.csdn.net/qq_62262918/article/details/135785412?spm=1001.2014.3001.5501导入依赖:

pom.xml:

html 复制代码
       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

实现步骤

首先我们先自定义一个注解

有了这个注解之后,我们可以在想要统计的方法上加上这个注解

名称随便起但要见名知意

代码如下:

java 复制代码
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author mijiupro
 */


@Retention(RetentionPolicy.RUNTIME)// 指定注解的保留策略为RUNTIME
@Target(ElementType.METHOD)// 指定该注解可以用于方法
public @interface MethodCallCount {
}

接下来定义一个切面

通过该切面来对这个注解进行增强处理

代码如下:

java 复制代码
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author mijiupro
 */

@Aspect// 声明这是一个切面
@Component// 声明这是一个Spring Bean(交给Spring管理)
@Slf4j
public class MethodCallCountAspect {
    // 用于存储方法调用次数的Map,使用ConcurrentMap保证线程安全
    private final Map<String, AtomicInteger> counterMap = new ConcurrentHashMap<>();
    @Around("@annotation(com.mijiu.commom.aop.annotation.MethodCallCount)")
    public Object methodCallCountAspect(ProceedingJoinPoint joinPoint) {

        String methodName = joinPoint.getSignature().toShortString();
        try{
            return joinPoint.proceed();
        }catch (Throwable ignored){
        //异常处理
            return null;
        }finally {
            AtomicInteger counter = counterMap.computeIfAbsent(methodName,k -> new AtomicInteger(0));
            counter.incrementAndGet();
            log.info("方法 {} 调用次数:{}", methodName, counter.get());
        }

    }

    // 提供一个方法,用于获取方法调用次数的Map
    public Map<String, AtomicInteger> getCounterMap() {
        return new ConcurrentHashMap<>(counterMap);
    }
}

需要统计方法上使用该注解

有了以上注解和切面后,只需要在我们想要统计的方法上使用该注解就行了

测试

启动项目调用一下接口

但是需要注意的是,这个统计结果只在内存中有效,如果应用发生重启,就会归零了。如果想要持久化保存,就需要考虑持久化存储了,如存在mysql或者redis中。

另外,如果并发特别高,对统计结果要求没那么精确,可以用LongAdder替代AtomicInteger

相关推荐
Chenyiax9 小时前
从 Chat 到 Responses:OpenAI API 抽象为什么变了?
后端
MariaH9 小时前
Koa和Express的区别
后端
MariaH10 小时前
Koa框架的使用
后端
luckdewei11 小时前
那个用 passlib 做认证的新同事,上线第一天就把用户密码写进了日志
后端
ping某12 小时前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
JustHappy12 小时前
我汇总了身边朋友的经历才发现,其实第一份实习是最难找的......
前端·后端·面试
uhakadotcom12 小时前
在python 的 工程化架构中 ,什么是 薄包装器层?
后端·面试·github
唐青枫16 小时前
Java JDBC 实战指南:从 Connection 到事务和连接池
java
用户14748530797416 小时前
CodeX使用Skill生成游戏美术和音乐资源,一分钟入门
后端
Melody12317 小时前
用 abort 中断 AI 流式请求,我之前做错了
后端