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

相关推荐
2301_803554521 小时前
C++联合体(Union)详解:与结构体的区别、联系与深度解析
java·c++·算法
EnCi Zheng1 小时前
SpringBoot 配置文件完全指南-从入门到精通
java·spring boot·后端
烙印6011 小时前
Spring容器的心脏:深度解析refresh()方法(上)
java·后端·spring
为什么我不是源代码1 小时前
JPA读取数据库离谱问题-No property ‘selectClassByName‘ found-Not a managed type
java·sql
Lisonseekpan1 小时前
Guava Cache 高性能本地缓存库详解与使用案例
java·spring boot·后端·缓存·guava
我真的是大笨蛋2 小时前
Redis的String详解
java·数据库·spring boot·redis·spring·缓存
心态特好2 小时前
Jwt非对称加密的应用场景
java
七七七七072 小时前
【Linux 系统】打开文件和文件系统
linux·运维·spring
敢敢J的憨憨L2 小时前
GPTL(General Purpose Timing Library)使用教程
java·服务器·前端·c++·轻量级计时工具库
3 小时前
JUC专题 - 并发编程带来的安全性挑战之同步锁
后端