feign在springCloud场景下进行动态url变更

springcloud中feignClient对原生feign进行了上层封装,得以在Spring环境下对开发人员有较好的细节屏蔽,如果想要跳出该封装,进行灵活的使用,如下场景:

  • 需要根据用户的配置,在不重启机器的情况下完成服务的切换
  • 大量的基础参数重复在各个接口间,或其他定制化操作(拦截器等)

这种情况下,需要使用原生feign,按以下几步即可:

  1. 定义调用接口(关键点:RequestLine)
    interface GitHub {
      @RequestLine("GET /repos/{owner}/{repo}/contributors")
      List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
    
      @RequestLine("POST /repos/{owner}/{repo}/issues")
      void createIssue(Issue issue, @Param("owner") String owner, @Param("repo") String repo);
    
    }
    
    public static class Contributor {
      String login;
      int contributions;
    }
    
    public static class Issue {
      String title;
      String body;
      List<String> assignees;
      int milestone;
      List<String> labels;
    }

     

  2. 使用(关键点:1⃣️Feign.builder()...; 2⃣️target(XX))
    public class MyApp {
      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("OpenFeign", "feign");
        for (Contributor contributor : contributors) {
          System.out.println(contributor.login + " (" + contributor.contributions + ")");
        }
      }
    }

    对于上步中的target,可以自定义实现,达到动态读取的效果,如下实际使用:

      @Bean
      public **FeignClient client(SpringEncoder encoder, SpringDecoder decoder) {
        return Feign.builder()
            .encoder(encoder)
            .decoder(decoder)
            .target(new Target<**FeignClient>() {
              @Override
              public Class<**FeignClient> type() {
                return **FeignClient.class;
              }
        
              @Override
              public String name() {
                return "***";
              }
        
              @Override
              public String url() {
                // 获取实时url
                return any.url();
              }
        
              @Override
              public Request apply(RequestTemplate input) {
                if (input.url().indexOf("http") != 0) {
                  input.insert(0, url());
                }
                // 读取并设置基本参数
                input.query("***", "**");
        
                return input.request();
              }
            });
      }

    3、使用方式与原feignClient无异:

    @Autowired
    private **FeignClient client;
    
    public void test() {
        // 调用
        client.***();
    }

    参考文档:https://github.com/OpenFeign/feign


版权声明:本文为GAOXINXINGgaoxinxing原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。