如何在 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 启动应用程序本机支持指标收集,包括简单的计数器。
是否可以创建一个自定义注释来简单地跟踪某些方法的调用,而不必在每个方法中显式添加服务方法调用?
@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 启动应用程序本机支持指标收集,包括简单的计数器。