划重点:文中提到的 Spring Cloud OpenFeign 和 OpenFeign 不是同一个东西!!!
关于区别:简单来讲 Spring Cloud OpenFeign 是基于 OpenFeign 进行包装,集成了 SpringMVC的注解等方便SpringBoot项目开发的一个组件。

OpenFeign github地址文档
Spring Cloud OpenFeign github地址官方主页官方文档

近期需要通过http调用一个url地址可能会发生变化的第三方api接口,由于之前使用过OpenFeign,自然想到用Feign来实现,而项目又是SpringCloud项目,再自然的想到了使用 Spring Cloud OpenFeign来实现。
简单概括就是:使用Spring Cloud OpenFeign实现 动态url的接口请求

其实之前就试过OpenFeign实现动态的url请求,相关分享在 跳转链接。 具体实现就是在接口方法加上 URI参数,该URI参数会动态替换掉原有的url。
而在Spring Cloud OpenFeign中,实现思路基本等同于OpenFeign,不过由于Spring Cloud OpenFeign集成了众多组件(ribbon、hystrix),所以相关配置还是有很多不同。

示例
maven依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-openfeign</artifactId>
	<version>2.1.2.RELEASE</version>
</dependency>

客户端代码

@FeignClient(name = "ThirdPartyAPI", url = "http://10.1.2.3:8080")
public interface IFeignClientAPI {
    @GetMapping("/query")
    String query(URI uri, @RequestParam("id") String id);// 增加 URI 参数!!!
}

// 调用方式:直接通过 @Autowired 注解自动注入
 @Autowired
 private IFeignClientAPI feignClient;
 
feignClient.query(new URI("http://127.0.0.1:80"), "testID"); 
//实际请求地址:http://127.0.0.1:80/query?id=testID

逐个解析下相关细节:

  • 接口方法的定义使用了SpringMVC的注解 @GetMapping@RequestParam,其实SpringMVC的其他注解在此处都是支持的。(有其他文章提到也支持OpenFeign原有的注解@RequestLine、@Param等,但博主实测是不支持的,相关解析类为 feign.Contract,这个存疑

  • 在使用方式上,OpenFeign需要手动构建代理对象,Spring Cloud OpenFeign 不同于 OpenFeign, Spring Cloud OpenFeign 帮我们自动生成了接口的代理对象(即实现类),并且注册到Spring中,我们可以很方便的使用 @Autowired 注入代理对象然后使用。其默认的代理对象是 LoadBalancerFeignClient。还有一个代理对象是 feign.Client.Default。两者区别在于:
    LoadBalancerFeignClient 通过服务名(下文提到)从Eureka查找相关的节点地址url,发起调用。
    feign.Client.Default 仅是简单的直接调用。

  • @FeignClient(name = "ThirdPartyAPI", url = "http://10.1.2.3:8080")
    name 属性是 @FeignClient 注解必要的!不定义时会报错,其默认指代Eureka上的服务名。
    url 属性,这是重点了! url属性指定什么值其实不重要,因为最终都会被方法的URI参数值替换掉,它在这里另一个重要的作用,就是将接口的代理对象变成feign.Client.Default(上文提到默认是LoadBalancerFeignClient),这样就绕过了从Eureka取节点地址这一步,毕竟第三方的地址不可能注册到我们的Eureka上。(相关细节可自行debug FeignClientFactoryBean.getTarget()

总结一下关键点:
  • @FeignClient 注解需要指定其 url 属性(值不重要)!
  • 接口方法定义增加 URI类型的参数!

接口方法定义SpringMVC的注解
使用@Autowired 注入代理对象可直接调用


end

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐