feign动态切换url方式实现

20 篇文章 0 订阅
20 篇文章 0 订阅

目录

1.概览(Overview)

2.详细说明(Details)

2.1 首先,定义调用接口

2.2 然后,构造可调用实例即可

2.3 接下来,展示一个实际的需求及使用示例

3.补充说明


1.概览(Overview)

springcloud中feignClient对原生feign进行了上层封装,得以在Spring环境下对开发人员有较好的细节屏蔽,方便了我们快捷的使用。

不过,有些时候我们想要跳出该封装,进行灵活的使用,比如以下场景:

  • 需要根据用户的配置,在不重启机器的情况下完成服务地址的切换,比如将临时传进来的参数作为基础地址
  • 大量的基础参数重复在各个接口间进行定义、传送,比如一些服务的基础参数:appId等(当然,Spring-cloud-netfix中的@Feignclient中的configuration也可以做同样的事,不过可以抛开Springcloud实现,深入看下feign内部结构)

这种情况下,则需要使用原生feign。

2.详细说明(Details)

接下来的介绍主要基于如何开发进行展开,分为三部分:

  • demo:定义调用接口
  • demo:如何进行调用
  • 真实场景实现及注意点

2.1 首先,定义调用接口

(主要使用@RequestLine标注method,代替Springcloud下的@Feignclient标注Class)

interface GitHub {

    // 接口类型 uri

    @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.2 然后,构造可调用实例即可

说明:仅为示例,真实使用时不建议每次直接build,尤其时调用量较大的接口

public class MyApp {

  public static void main(String... args) {

    // 使用时进行构造

    GitHub github = Feign.builder()

                         .decoder(new GsonDecoder())

                         .target(GitHub.class"https://api.github.com");//传入url

   

    // 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 + ")");

    }

  }

}

实际项目使用过程中,不可能每次调用均新建feign实例,内存开销将会很大。

2.3 接下来,展示一个实际的需求及使用示例

(1) 需求描述

  • 产品需要对接一个外部系统openapi,但是此外部系统的详细信息需要通过界面配置(即运维人员在后期可灵活更改该系统地址而无需重启后台服务)进行灵活替换
  • 界面配置外部系统地址后立即生效

(2) 本示例实现如下能力

  • 根据外部接口方式(使用某个service作为获取源)作为feignclient的基础地址
  • 在feignclient构造时将其公共不变参数固定(从而无需在接口中重复定义和传入)

(3) 源码展示

  1. 接口定义

    interface CustomFeignClient {

        // 接口类型 uri

        @RequestLine("GET /test/{resourceId}/list")

        List<String> list(@Param("resourceId") String resourceId);

    }

  2. feignclient构造及发布

    @Autowired

    private DynamicUrlService dus;

     

    @Bean

    public CustomFeignClient client(SpringEncoder encoder, SpringDecoder decoder) {

      return Feign.builder()

          .encoder(encoder)//编码器

          .decoder(decoder)//解码器

          .target(new Target<CustomFeignClient>() {

            @Override

            public Class<CustomFeignClient> type() {

              return CustomFeignClient.class;

            }

       

            @Override

            public String name() {

              return "***";

            }

       

            @Override

            public String url() {

              // 获取实时url

              return dus.url();

            }

       

            @Override

            public Request apply(RequestTemplate input) {

              if (input.url().indexOf("http") != 0) {

                input.insert(0, url());

              }

              // 读取并设置基本参数,与Spring cloud netfix中的拦截器中apply功能一样

              input.query("***""**");

       

              return input.request();

            }

          });

    }

  3. 最后,可以正常调用该feignclient

    @Autowired

    private CustomFeignClient client;

     

    public void test() {

        // 调用

        client.list(“testId”);

    }

 

此方式相较于demo中的方式,可以避免频繁创建client,而且保证了动态性。

3.补充说明

以上展示了一个动态切换url需求,并以原生feign构造的方式进行了实现,此方式在Spring cloud体系下不建议使用(除非特定的需求),因为会破坏负载均衡等机制。

 

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

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值