目录
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)
|
2.2 然后,构造可调用实例即可
说明:仅为示例,真实使用时不建议每次直接build,尤其时调用量较大的接口
|
实际项目使用过程中,不可能每次调用均新建feign实例,内存开销将会很大。
2.3 接下来,展示一个实际的需求及使用示例
(1) 需求描述
- 产品需要对接一个外部系统openapi,但是此外部系统的详细信息需要通过界面配置(即运维人员在后期可灵活更改该系统地址而无需重启后台服务)进行灵活替换
- 界面配置外部系统地址后立即生效
(2) 本示例实现如下能力
- 根据外部接口方式(使用某个service作为获取源)作为feignclient的基础地址
- 在feignclient构造时将其公共不变参数固定(从而无需在接口中重复定义和传入)
(3) 源码展示
-
接口定义
interface
CustomFeignClient {
// 接口类型 uri
@RequestLine
(
"GET /test/{resourceId}/list"
)
List<String> list(
@Param
(
"resourceId"
) String resourceId);
}
-
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();
}
});
}
-
最后,可以正常调用该feignclient
@Autowired
private
CustomFeignClient client;
public
void
test() {
// 调用
client.list(“testId”);
}
此方式相较于demo中的方式,可以避免频繁创建client,而且保证了动态性。
3.补充说明
以上展示了一个动态切换url需求,并以原生feign构造的方式进行了实现,此方式在Spring cloud体系下不建议使用(除非特定的需求),因为会破坏负载均衡等机制。