我有以下Spring Boot类,并用自定义注释Counted
进行了注释:
@RestController
@RequestMapping("/identity")
public class IdentityController {
@Autowired
private IdentityService identityService;
@PostMapping
@Counted(value = "post_requests_identity")
public Integer createIdentity() {
return identityService.createIdentity();
}
}
Counted
注释的定义如下:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface Counted {
String value();
}
我想要编写一个注释处理器,以有效地使我的Controller的行为类似于以下代码。
@RestController
@RequestMapping("/identity")
public class IdentityController {
@Autowired
private IdentityService identityService;
@Autowired
private PrometheusMeterRegistry registry;
@PostConstruct
public void init() {
registry.counter("post_requests_identity");
}
@PostMapping
public Integer createIdentity() {
registry.counter("post_requests_identity").increment();
return identityService.createIdentity();
}
}
我已经能够在运行时通过反射来做到这一点,但这大大延长了启动时间。是否可以仅使用注释和自定义注释处理器来完成上述操作?简而言之,我想创建一个注释,该注释将带注释的方法添加到类中,并向已存在的方法添加任意方法调用。
我知道注释处理实际上并不支持修改源。我很想知道其他任何方法来执行上述操作,而无需将注册表及其相关代码直接放在源代码中。
答案 0 :(得分:0)
您绝对可以制作自己的拦截器,也可以创建自己的PostProcessor
。但是,Spring具有一个不错的内置功能(Application Events)(该功能实际上已在整个框架中使用)。这是一件很有趣的事情,它通过一个恰好适合您需求的漂亮抽象将DI和Spring用作总线。 (有关更多信息,另请参见this blog文章。)
从filepath: {endswith}
接受方面,您可以进行如下设置:
ApplicationEvent
从发送方开始,您可以使用自定义批注轻松地从您在问题中遗漏的地方继续:
// Create an ApplicationEvent type for your "count" event like so...
public class CountEvent extends ApplicationEvent {
private String counterName;
...
}
// Create a class that accepts the count events and meters them...
@Component
public class MeterEventService {
@Autowired
private PrometheusMeterRegistry registry;
@EventListener
public void createIdentity(CountEvent countEvent) {
String countedMethod = countEvent.getCounterName();
registry.counter(countedMethod).increment();
}
}
恕我直言,对于拥有这样一个功能的极大方便,这不是太多的代码。
此外,如果您更愿意使用@Component
@Aspect
public class Mail {
// Autowire in ApplicationContext
private ApplicationContext applicationContext;
@After("execution (@<package to annotation>.Counted * *(..))")
public void countMetric(JoinPoint jp){
MethodSignature signature = (MethodSignature) jp.getSignature();
String method = signature.getMethod().getName();
applicationContext.publishEvent(new CountEvent(method));
}
}
中的value
而不是方法名,则可以类似地doing this提取注释。