在Feign RequestInterceptor / RequestTemplate中访问URITemplate或RequestLine值

问题描述 投票:8回答:1

我正在针对具有硬api速率限制的云应用程序开发应用程序。为了让我的团队了解我们与这些限制有多接近,我想以有意义的方式计算从我们的应用程序发出的所有API调用。

我们使用Feign作为访问层,我希望能够使用RequestInterceptor来计算我们调用的不同API端点:

RequestInterceptor ri = rq -> addStatistics(rq.url());

现在这不起作用,因为结果URL之后几乎总是计为“1”,因为它们已经包含所有已解析的路径变量,所以我得到了计数

1 - /something/id1valueverycryptic/get
1 - /something/anothercrypticidkey/get

等等。

我希望以某种方式访问​​@ResuqestLine映射值(GET /something/{id}/get)或至少uri模板预解析(/somethine/{id}/get

有没有办法做到这一点?

谢谢!

java spring-boot netflix-feign
1个回答
3
投票

也许你可以尝试使用自定义假装InvocationHandlerFactory。

我设法使用这样的代码记录RequestInterceptor:

  • 更改EnableFeignClients并添加defaultConfiguration @EnableFeignClients(defaultConfiguration = FeignConfig.class)
  • 添加默认的feign配置 @Configuration public class FeignConfig { @Bean @ConditionalOnMissingBean public Retryer feignRetryer() { return Retryer.NEVER_RETRY; } @Bean @Scope("prototype") @ConditionalOnMissingBean public Feign.Builder feignBuilder(Retryer retryer) { return Feign.builder() .retryer(retryer) .invocationHandlerFactory((target, dispatch) -> new CountingFeignInvocationHandler(target, dispatch)); } }
  • 创建您的调用处理程序(基于feign.ReflectiveFeign.FeignInvocationHandler的代码) public class CountingFeignInvocationHandler implements InvocationHandler { private final Target target; private final Map<Method, MethodHandler> dispatch; public CountingFeignInvocationHandler(Target target, Map<Method, MethodHandler> dispatch) { this.target = checkNotNull(target, "target"); this.dispatch = checkNotNull(dispatch, "dispatch for %s", target); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ("equals".equals(method.getName())) { try { Object otherHandler = args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null; return equals(otherHandler); } catch (IllegalArgumentException e) { return false; } } else if ("hashCode".equals(method.getName())) { return hashCode(); } else if ("toString".equals(method.getName())) { return toString(); } RequestLine requestLine = method.getAnnotation(RequestLine.class); addStatistics(requestLine.value()); return dispatch.get(method).invoke(args); } @Override public boolean equals(Object obj) { if (obj instanceof CountingFeignInvocationHandler) { CountingFeignInvocationHandler other = (CountingFeignInvocationHandler) obj; return target.equals(other.target); } return false; } @Override public int hashCode() { return target.hashCode(); } @Override public String toString() { return target.toString(); } }

小心并检查假装配置是否不复杂,在这种情况下根据需要扩展类。

© www.soinside.com 2019 - 2024. All rights reserved.