如何在 Spring 中创建调用计数器注释?

How to create an invocation counter annotation in Spring?

是否可以创建一个自定义注释来简单地跟踪某些方法的调用,而不必在每个方法中显式添加服务方法调用?

@InvocationCounter(path = "/test1") //I'm looking for this
@GetMapping("/person/{id}")
public Person getPerson(Long id) {
    //...
}

在每次 getPerson() 调用时,我想要一个调用计数器来记录调用,例如:

@Service
public class InvocationCounterService {
      Map<String, AtomicInteger> counter;

      public void count(String path) {
          if (counter.get(path) == null) counter.put(path, new AtomicInteger()));
          counter.get(path).incrementAndGet();          
      }

      @Scheduled(fixedRate = 60000)
      public void persist() {
              //optionally process or persist the invocations
      }
}

问题:我怎么可能告诉 Spring 在每个带注释的控制器方法上调用 count() 服务方法?

注释是语法元数据的一种形式,可以添加到 Java 源代码。 因此,您可以使用注释向源添加信息,但不能添加要执行的代码。

您可以按照 pleft 在评论中提到的方面进行处理。

或者您可以创建一个 countExecutions 函数,将您的 Function 作为 lambda 表达式来计算执行次数,如下所示:

 public R countExecutions(Function<R, T> fun, T data) {
     // invoke counter
     return fun.apply(data);
 } 

并将您的代码重写为

@GetMapping("/person/{id}")
public Person getPerson(Long id) {
    return countExecutions( /* code previously in the getPerson as a Function */ , id);
}

注解InvocationCounter:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InvocationCounter {
    String path();
}

方面 InvocationCounterAspect:

@Aspect
@Component
public class InvocationCounterAspect {

    @Autowired
    InvocationCounterService invocationCounterService;

    @Around("@annotation(InvocationCounter)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        InvocationCounter invocationCounter = signature.getMethod().getAnnotation(InvocationCounter.class);
        
        final String path = invocationCounter.path(); //retrieve path from the annotation

        invocationCounterService.count(path);  //call the counter service
        return joinPoint.proceed(); //proceed executing the annotated method
    }
}

您应该查看 micrometer.io,Spring 启动应用程序本机支持指标收集,包括简单的计数器。