我的团队正在将我们的Spring MVC扩展迁移到WebFlux。
我们有一项功能,可让我们的客户自定义控制器方法的指标。为此,我们创建了由HandlerInterceptorAdapter处理的注释。
问题是我在Spring WebFlux中看不到任何等效的东西。我无法使用WebFilter,因为Spring尚不知道将调用哪个端点。我该如何实施?
我发现最接近的解决方法是使用RequestMappingHandlerMapping并以某种方式构建Map<String(path), HandlerMethod>
的映射,但是在我看来,这很麻烦且容易出错。
有没有更好的方法来解决这个问题?
编辑:
像这样
public class MeteredHandlerInterceptor extends HandlerInterceptorAdapter {
public MeteredHandlerInterceptor() {
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// I save start time of method
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// I read endpoint method from the HandlerMethod, I apply any customisation by our custom @MeteredEndpoint annotation (for example custom name) and I save it in MeterRegistry
}
}
我还没有编码变通方法,因为我不想花时间在上面,但是我看到我可以获得HandlerMethod
的路径,但是我不确定是否会收到相同的{{1 }},就像我通常在调用控制器时一样。
答案 0 :(得分:0)
也许有点晚了,但它仍然对某人有用...
我还没有找到一种简单的方法来做到这一点,我能创建的最好的方法是一个 HandlerAdapter
bean,它以以下方式拦截处理:
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public HandlerAdapter handlerAdapter(RequestMappingHandlerAdapter requestMappingHandlerAdapter) {
return new HandlerAdapter() {
@Override
public boolean supports(Object handler) {
return handler instanceof HandlerMethod;
}
@Override
public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
// your stuff here...
// e.g. ((HandlerMethod) handler).getMethod().getAnnotations()...
return requestMappingHandlerAdapter.handle(exchange, handler);
}
};
}
这个想法是这个适配器用于所有 HandlerMethod
处理程序(那些是通过从 @Controllers
收集带注释的方法创建的)并将处理委托给 RequestMappingHandlerAdapter
(这将在正常情况下直接用于 HandlerMethod
处理程序,注意这里的 @Order 注释)。
关键是您可以将代码放在调用句柄方法之前/之后,并且您知道此时正在调用的方法。