Feign 线程安全吗...?

Is Feign threadsafe...?

Feign 线程实例安全吗...?我找不到任何支持这一点的文档。有没有人不这么认为?

这是在 github repo 上为 Feign 发布的标准示例...

interface GitHub {
  @RequestLine("GET /repos/{owner}/{repo}/contributors")
  List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
}

static class Contributor {
  String login;
  int contributions;
}

public static void main(String... args) {
  GitHub github = Feign.builder()
                       .decoder(new GsonDecoder())
                       .target(GitHub.class, "https://api.github.com");

  // Fetch and print a list of the contributors to this library.
  List<Contributor> contributors = github.contributors("netflix", "feign");
  for (Contributor contributor : contributors) {
    System.out.println(contributor.login + " (" + contributor.contributions + ")");
  }
}

我应该将其更改为以下...它是线程安全的...吗?

interface GitHub {
  @RequestLine("GET /repos/{owner}/{repo}/contributors")
  List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
}

static class Contributor {
  String login;
  int contributions;
}

@Component
public class GithubService {

  GitHub github = null;

  @PostConstruct
  public void postConstruct() {
    github = Feign.builder()
                .decoder(new GsonDecoder())
                .target(GitHub.class, "https://api.github.com");
  }

  public void callMeForEveryRequest() {
    github.contributors... // Is this thread-safe...?
  }
}

对于上面的示例...我使用了基于 spring 的组件来突出显示单例。提前致谢...

我也在找,可惜一无所获。在Spring 配置中提供的唯一标志。构建器在作用域原型中被定义为 bean,因此不应该是线程安全的。

@Configuration
public class FooConfiguration {
    @Bean
    @Scope("prototype")
    public Feign.Builder feignBuilder() {
        return Feign.builder();
    }
}

参考:http://projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-feign-hystrix

This 讨论似乎表明它 线程安全的。 (谈论创建一个效率低下的新对象) 查看源代码,似乎没有任何状态会使其不安全。这是意料之中的,因为它是仿照 Target 球衣设计的。但是在以不安全的方式使用它之前,您应该从 Feign 开发人员处获得确认或进行自己的测试和审查。

在深入研究 feign-core 代码和其他几个伪装模块之后(我们需要对不存在的东西的额外支持,所以我不得不修改一些东西——另外,这个问题让我很好奇,所以我又看了一眼),看起来你应该是安全的 re-using 在 multi-threaded 环境中伪装客户端,只要你所有的本地代码(例如任何自定义 EncoderExpander,或 RequestInterceptor 类,等等)没有可变状态。

Feign 内部不会以可变状态的方式存储太多内容,但有些东西会被缓存并且 re-used(因此如果您调用 Feign,可能会同时从多个线程调用target 的方法同时来自多个线程),所以你的插件应该是无状态的。

在我看来,所有主要 Feign 模块在编写时都以不变性和无状态为目标。

在feign/core/src/main/java/feign/Client.java,有评论

/** * 提交 HTTP {@link 请求请求}。实现应该是线程安全的。 */ public 接口客户端 {

所以,从设计者的角度来说,应该是线程安全的。