feignclient各种使用技巧说明
FeignClient常见用法
常规的FeignClient的创建与使用我相信只要使用过spring cloud全家桶的套件的基本上都是非常熟悉了,我们只需定义一个interface,然后定义相关的远程接口方法签名及在方法上标记相关的请求映射的注解指明请求URL及方式,最后在该接口类上方标记@FeignClient注解,并设置相关参数即可,示例模板如下所示:
/**
* 自定义一个FeignClient标准接口类
* @author zuowenjunn.cn
*/
@FeignClient(name = "baidu",url = "http://www.baidu.com")
public interface DemoFeignClient {
@RequestMapping(value = "/s",produces ="text/html",consumes = "text/html")
String searchBaiDu(@RequestParam("wd") String wd);
}
用法就比较简单了,直接把上述标记为@FeignClient的接口类(如:DemoFeignClient)当成普通BEAN的接口进行依赖注入即可,如下示例代码:
@Autowired
private DemoFeignClient demoFeignClient;
String searchResultResp = demoFeignClient.searchBaiDu("梦在旅途");
System.out.println("searchBaiDu Result:" + searchResultResp);
注意了,如上述示例代码均只是为了便于演示而创建的,确实可以拿来(复制到JAVA的spring cloud项目中)即可执行,但实际生产项目中使用则应根据实际的微服务的名称及URL来灵活配置,具体配置与使用可参见我(梦在旅途)之前的文章:玩转Spring Cloud之服务注册发现(eureka)及负载均衡消费(ribbon、feign)
上述通过定义接口+@FeignClient注解的方式是最常见也是最简单的使用的方式,那大家知悉原理吗?其实原理我在之前文章也讲过,核心点就是:在Spring IOC容器初始化时,会通过@EnableFeignClients中的@Import(FeignClientsRegistrar.class)最终执行FeignClientsRegistrar.registerBeanDefinitions方法,把所有标记有@FeignClient注解的接口包装成FeignClientFactoryBean并注册为BEAN,当项目中实际依赖FeignClient接口类时,则会通过FeignClientFactoryBean.getObject来生成真实的FeignClient接口的实现类BEAN,详细源码解读可参见:https://blog.csdn.net/forezp/article/details/83896098 这里面最关键的其实就是FeignClientFactoryBean.getObject方法,而这个方法本质又是调getTarget方法,这个方法最终返回的就是一个Targeter接口的实现类。如果我们想动态自定义一个FeignClient接口,增加一些自定义的逻辑(比如:额外装饰一些逻辑),那么我们只需要自行创建Targeter接口的实现类即可。这种方案是可行的,而且框架也提供了这种自定义的扩展能力:Feign.Builder,Feign.Builder类就是可以实现动态构建FeignClient的利器,下面我将基于这种思路实现动态自定义构建FeignClient。
动态自定义构建FeignClient实现方式一(直接指明服务的URL地址【如果是实际项目中这应该是网关的负载均衡地址哦】)
/**
* 自定义一个FeignClient接口类,除了不用加@FeignClient注解外,其余均相同
* @author zuowenjunn.cn
*/
public interface CustomApiFeignClient {
@RequestMapping(value = "/s",produces ="text/html",consumes = "text/html")
String searchBaiDu(@RequestParam("wd") String wd);
}
/**
* 定义配置类,集中动态配置自定义的FeignClient代理类BEAN
* @author zuowenjun.cn
*/
@Configuration
@Import(FeignClientsConfiguration.class)
public class FeignClientConfig {
@Bean
public CustomApiFeignClient customApiFeignClient(Contract contract, Decoder decoder, Encoder encoder) {
return Feign.builder().contract(contract).encoder(encoder).decoder(decoder).target(CustomApiFeignClient.class, "http://www.baidu.com");
}
}
用法就比较简单了,如常规用法一样,把视为FeignClient接口(如:CustomApiFeignClient)依赖注入到相关的BEAN中即可,代码如下所示:
CustomApiFeignClient feignClient = SpringUtils.getBean(CustomApiFeignClient.class); //这里使用工具类获取BEAN,当然也可以使用@Autowired注解方式获得
String searchResultResp = feignClient.searchBaiDu("梦在旅途");
System.out.println("searchBaiDu Result:" + searchResultResp);
动态自定义构建FeignClient实现方式二(直接指明服务名,并进行装饰,支持自定义负载均衡、更换请求API的组件等功能)
/**
* 自定义一个FeignClient接口类,除了不用加@FeignClient注解外,其余均相同
* @author zuowenjunn.cn
*/
public interface CategoryTreeConfigFeignClient {
@RequestMapping(value = "/categoryTreeConfig/getCategoryInfo", method = RequestMethod.POST)
ResponseData<Object> getCategoryInfo(CategoryTreeConfigBO categoryTreeConfigBO);
}
/**
* 定义配置类,集中动态配置自定义的FeignClient代理类BEAN
* @author zuowenjun.cn
*/
@Configuration
@Import(FeignClientsConfiguration.class)
public class FeignClientConfig {
@Bean
public CustomApiFeignClient customApiFeignClient(Contract contract, Decoder decoder, Encoder encoder) {
return Feign.builder().contract(contract).encoder(encoder).decoder(decoder).target(CustomApiFeignClient.class, "http://www.baidu.com");
}
@Bean
public CategoryTreeConfigFeignClient categoryTreeConfigFeignClient(@Qualifier("feignClient") Client client, SpringClientFactory clientFactory, Contract contract, Decoder decoder, Encoder encoder) {
Client customClient = new Client.Default(null, null) {
@Override
public Response execute(Request request, Request.Options options) throws IOException {
return super.execute(request, options);
}
@Override
public HttpURLConnection getConnection(URL url) throws IOException {
String serviceName = url.getHost();
String rawUrl= url.toString();
List<Server> upServers= clientFactory.getLoadBalancer(serviceName).getReachableServers();
//TODO:自定义客户端负载均衡策略,这里只是举例选第1个
Server bestServer= upServers.stream().findFirst().orElse(null);
Assert.notNull(bestServer,serviceName +":从注册中心没有找到可用的Server实例.");
url=new URL(url.getProtocol(),bestServer.getHost(),bestServer.getPort(),url.getFile());
return super.getConnection(url);
}
};
return Feign.builder().client(customClient).contract(contract).encoder(encoder).decoder(decoder).target(CategoryTreeConfigFeignClient.class, "http://微服务名");
}
}
实际用法与上述实现方式一相同,如下:
CategoryTreeConfigFeignClient categoryTreeConfigFeignClient=SpringUtils.getBean(CategoryTreeConfigFeignClient.class);//这里使用工具类获取BEAN,当然也可以使用@Autowired注解方式获得
ResponseData<Object> responseData= categoryTreeConfigFeignClient.getCategoryInfo(new CategoryTreeConfigBO(){
{
setId("50");
setIncludeChild(0);
}
});
除了上述通过Feign.builder()的方式来直接进行额外自定义处理处,还可以在常规用法的基础上增加个性化配置的方式来实现,即:给@FeignClient注解属性configuration赋值自定义的配置类,在配置类中可以定义相关的BEAN以替换全局默认的BEAN,具体方法请参见网上的相关文章介绍。
feignclient各种使用技巧说明的更多相关文章
- 通过实现仿照FeignClient框架原理的示例来看清FeignClient的本质
前言 FeignClient的实现原理网上一搜一大把,此处我就不详细再说明,比如:Feign原理 (图解) - 疯狂创客圈 - 博客园 (cnblogs.com),而且关于FeignClient的使用 ...
- 编程小技巧之 Linux 文本处理命令
合格的程序员都善于使用工具,正所谓君子性非异也,善假于物也.合理的利用 Linux 的命令行工具,可以提高我们的工作效率. 本文简单的介绍三个能使用 Linux 文本处理命令的场景,给大家开阔一下思路 ...
- 探究javascript对象和数组的异同,及函数变量缓存技巧
javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...
- 前端极易被误导的css选择器权重计算及css内联样式的妙用技巧
记得大学时候,专业课的网页设计书籍里面讲过css选择器权重的计算:id是100,class是10,html标签是5等等,然后全部加起来的和进行比较... 我只想说:真是误人子弟,害人不浅! 最近,在前 ...
- 前端网络、JavaScript优化以及开发小技巧
一.网络优化 YSlow有23条规则,中文可以参考这里.这几十条规则最主要是在做消除或减少不必要的网络延迟,将需要传输的数据压缩至最少. 1)合并压缩CSS.JavaScript.图片,静态资源CDN ...
- 工欲善其事,必先利其器 之 VS2013全攻略(安装,技巧,快捷键,插件)!
如有需要WPF工具的朋友可以移步 工欲善其事,必先利其器 之 WPF篇: 随着开发轨迹来看高效WPF开发的工具和技巧 之前一篇<c++的性能, c#的产能?!鱼和熊掌可以兼得,.NET NATI ...
- 15个关于Chrome的开发必备小技巧[译]
谷歌Chrome,是当前最流行且被众多web开发人员使用的浏览器.最快六周就更新发布一次以及伴随着它不断强大的开发组件,使得Chrome成为你必备的开发工具.例如,在线编辑CSS,console以及d ...
- Git小技巧 - 指令别名及使用Beyond Compare作为差异比较工具
前言 本文主要写给使用命令行来操作Git的用户,用于提高Git使用的效率.至于使用命令还是GUI(Tortoise Git或VS的Git插件)就不在此讨论了,大家根据自己的的喜好选择就好.我个人是比较 ...
- 【工具使用】mac电脑使用技巧
本文地址 分享提纲: 1. mac命令行和finder的交互 2. 一些mac的插件 3. 一些开发的配置 1.mac命令行和findder交互 1)命令行中打开当前文件夹: o ...
随机推荐
- CF346E-Doodle Jump【类欧】
正题 题目链接:https://www.luogu.com.cn/problem/CF346E 题目大意 给出\(a,n,p,h\),在每个\(ax\%p(x\in[0,n])\)的位置有一个关键点, ...
- 关于Postman你必须学会的技能
关于Postman 工欲善其事,必先利其器,在了解了接口测试之后,就要选择一款适用的工具.之所以选择postman是因为它简单.容易上手.能覆盖大多数HTTP接口测试场景,性价比极高. Postman ...
- react-native移动端设置android闪屏页
前言 因为app启动时会白屏一段时间,导致让人用起来非常的不舒服,后来了解一下知道这叫做闪屏 于是着手解决这个白屏的问题,换个颜色?不行,不如用一张好看的图片来替换,这样才让人看起来更加舒服. 那么该 ...
- Fortran学习笔记:02 流控制语句
Fortran学习笔记目录 书接上回:Fortran学习笔记:01 基本格式与变量声明 流控制语句 IF语句 IF (逻辑表达式) THEN ... ELSE ... END IF SELECT-CA ...
- 从零入门 Serverless | Serverless Kubernetes 应用部署及扩缩容
作者 | 邓青琳(轻零) 阿里云技术专家 导读:本文分为三个部分,首先给大家演示 Serverless Kubernetes 集群的创建和业务应用的部署,其次介绍 Serverless Kuberne ...
- Clusternet v0.5.0 重磅发布: 全面解决多集群应用分发的差异化配置难题
作者 徐迪,腾讯云容器技术专家. 汝英哲,腾讯云高级产品经理. 摘要 在做多集群应用分发的时候,经常会遇到以下的差异化问题,比如: 在分发的资源上全部打上统一的标签,比如 apps.my.compan ...
- zlib开发笔记(四):zlib库介绍、编译windows vs2015x64版本和工程模板
前言 Qt使用一些压缩解压功能,介绍过libzip库编译,本篇说明zlib库.需要用到zlib的msvc2015x64版本,编译一下. 版本编译引导 zlib在windows上的mingw32 ...
- 2020BUAA软工提问回顾和个人总结作业
2020BUAA软工提问回顾和个人总结作业 17373010 杜博玮 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 提问回顾和个人总结作业 我在 ...
- linux 蓝牙开发调试(rtl8821cs模块)
刚调完rtl8821cs的wifi功能,项目需要打通蓝牙配网功能. 调试过程中遇到各种问题中间几乎放弃,倒腾了几天最后还是打通了,顺便记录下过程. 通信接口:SDIO @WiFi.Uart @BT;工 ...
- wpa_supplicant启动出错rfkill: Cannot open RFKILL control device
在板子是调试网络,千辛万苦把wpa_supplicant及其依赖都移植编译进来了,在板子上调试启动的时候启动报错了 D/wpa_supplicant( 1152): wpa_supplicant v2 ...