撸了一个 Feign 增强包
前言
最近准备将公司的一个核心业务系统用 Java
进行重构,大半年没写 Java
,JDK
都更新到 14 了,考虑到稳定性等问题最终还是选择的 JDK11
。
在整体架构选型时,由于是一个全新的系统,所以没有历史包袱,同时团队中也有多位大牛坐镇,因此我们的选项便大胆起来。
最终结果就是直接一把梭,直接上未来的大趋势:Service Mesh
,直接把什么 SpringCloud
、Dubbo
这类分布式框架全部干掉。
本次的重点不是讨论 Service Mesh
是什么、能解决什么问题、为什么选择它,毕竟我也在学习阶段,啥时候整明白线上也稳定了再和大家来交流。
问题
既然方向定了就开始实际撸码了,不过刚一开始就验证了”理想很丰满、现实很骨感“;
由于我们去掉了 SpringCloud
和 Dubbo
这类框架,服务的注册、发现、负载均衡等需求全部都下沉到 Service Mesh
中提供了。
但对于开发来说依然希望可以调用本地方法的方式来调用远程服务,这在 SpringCloud
这类框架中是很容易实现的,框架本身就有很好的支持。
回到我们这个场景,需求其实很简单,就是想达到 SpringCloud
中的 Feign
这样的声明式+注解的方式调用。
@Autowired
private StoreClient client ;
Store store = client.update(1, store)
使用 spring-cloud-openfeign
这个包其实就能实现上述的需求了,但这样会引入一些我们根本不会使用的 SpringCloud
的相关依赖,让人感觉”不干净了“;同时也和 Service Mesh
的理念相反,其中的一大目的就是要降低这类框架的侵入性。
其实 spring-cloud-openfeign
的核心就是 Feign,本身它也是可以开箱即用的,所以便尝试看 Feign
自己是否支持这样的用法。
通过官方文档可以得知:是可以定义接口的形式来调用远程接口的,但它本质上是不依赖其他库便可以使用,所以它本身是没有和 Spring
整合也是合情合理,但也就造成了没有现成库可供我们使用。
我们自然是不想写上图红框处的代码的,希望所有接口直接注入就可以使用。
使用
因此结合以上的需求便有了这个库 feign-plus
它的使用流程其实就是翻版的 spring-cloud-openfeign
:
@FeignPlusClient(name = "github", url = "${github.url}")
public interface Github {
@RequestLine("GET /repos/{owner}/{repo}/contributors")
List<GitHubRes> contributors(@Param("owner") String owner, @Param("repo") String repo);
}
在 SpringBoot
入口进行扫描:
@SpringBootApplication
@EnableFeignPlusClients(basePackages = "top.crossoverjie.feign.test")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
在 Spring
上下文中直接注入使用:
@Autowired
private Github github ;
List<GitHubRes> contributors = github.contributors("crossoverJie", "feign-plus");
logger.info("contributors={}", new Gson().toJson(contributors));
所以当我们需要调用一些外部第三方接口时(比如支付宝、外部 OpenAPI)便可类似于这样定义一个接口,把所有 HTTP 请求的细节屏蔽掉。
当然也适合公司内部之间的服务调用,和咱们以前写 SpringCloud
或 Dubbo
时类似;服务提供方提供一个 Client
包,消费方直接依赖便可以调用。其他的负载均衡、容错之类的由 Service Mesh
替我们完成。
对于内部接口,也可以加上 @RequestMapping("/path")
注解:
在请求时便会在 url 后拼接上 /order
,这样在配置 feign.order.service.url
时只需要填入服务提供方的域名或 IP 即可。
feign-plus
也支持切换具体的 httpclient,默认是 okhttp3
,通过以下配置便可更改。
# default(okhttp3)
feign.httpclient=http2Client
当然也有其他相关配置:
feign.plus.max-idle-connections = 520
feign.plus.connect-timeout = 11000
feign.plus.read-timeout = 12000
实现
最后简单聊聊是如何完成的吧,其实本质上就是 spring-cloud-openfeign
的浓缩版。
其中最为核心的便是 top.crossoverjie.feign.plus.factory.FeignPlusBeanFactory
类。
该类实现了 org.springframework.beans.factory.FactoryBean
接口,并重写了 getObject()
方法返回一个对象。
这段代码是不是似曾相识,其实就是
Feign
的官方demo
。
这里所返回的对象其实就是我们定义的接口的代理对象,而这个对象本身则是 Feign
,所以再往里说:我们的 http
请求编解码、发起请求等逻辑又被这个 feign
对象所代理了。
这个 HardCodedTarget
则是 Feign
内部用于代理最终请求的对象。
有一个小难受的地方:这样的自己定义 Bean 然后注入对象 Idea 是识别不了的,认为当前上下文没有该 Bean,但是 spring-cloud-openfeign 却可以识别。
由于 Feign
支持多个客户端,所以这里的客户端可以通过配置文件动态指定。
利用 SpringBoot
提供的 @ConditionalOnExpression
注解可以根据配置动态的选择使用哪个 httpclient
,也就是动态选择生成哪个 Bean
。
总结
这个库的逻辑非常简单,本质上就是封装了 Feign
并提供了 SpringBoot
的支持,欢迎有类似需求的朋友下载使用。
feign-plus
源码:https://github.com/crossoverJie/feign-plus
你的点赞与分享是对我最大的支持
撸了一个 Feign 增强包的更多相关文章
- 撸了一个 Feign 增强包 V2.0 升级版
前言 大概在两年前我写过一篇 撸了一个 Feign 增强包,当时准备是利用 SpringBoot + K8s 构建应用,这个库可以类似于 SpringCloud 那样结合 SpringBoot 使用声 ...
- virtualbox安装增强包及配置共享文件夹
因为需要在host及虚拟机间传输数据,想使用共享文件夹.但是单独设置了共享文件夹后在centos里找不到共享文件夹,看了下要安装增强包.好吧,顺 便也解决下鼠标切换的问题,省的老是按右CTL切换 ...
- 【转】virtualbox安装增强包及配置共享文件夹
原文网址:http://www.2cto.com/os/201308/233609.html virtualbox安装增强包及配置共享文件夹 因为需要在host及虚拟机间传输数据,想使用共享文 ...
- 虚拟机 minimal 安装增强包
在虚拟机下安装了一个centos的minimal镜像,发现增强包不能安装,鼠标不能在虚拟机和物理机间自由切换.不能共享粘贴板,非常是不爽,这里摸索出在centos minimal OS下安装增强包的 ...
- VirtualBox安装增强包实现文件共享
环境: win10 64位 Virtualbox 5.1.30 ubuntu-16.04.3-server-amd64.iso 1. 安装好ubuntu后,打开virtualbox安装路径文件夹,找到 ...
- virtualbox中新版本Ubuntu安装软件增强包后重启无限登录界面的解决办法
原来我虚拟机版本是4.2.10,装的Ubuntu3.3,因为版本过老使用出现了一些问题,于是换成14.04,安装成功,但是装增强包的时候,装完重启,无限登录界面,密码是对的. 看了网上的很多方法,什么 ...
- 使用Dockerfile创建一个tomcat镜像,并运行一个简单war包
docker已经看了有一段时间了,对镜像和容器也有了一个大致了解,参考书上的例子制作一个tomcat镜像,并简单运行一个HelloWorld.war 1.首先下载linux环境的tomcat和jdk, ...
- 创建你的第一个Composer/Packagist包
今天我们要介绍一下如何通过Composer和Packagist向PHP社区贡献代码包.首先,如果你是一个PHP开发者但是还不知道什么是Composer,请先参考了一下这篇文章http://docs.p ...
- python 如何编写一个自己的包
python 如何编写一个自己的包 先写function 内容 package/wadepypk$ ls __init__.py f1.py f2.py f1.py def show(): print ...
随机推荐
- java语言基础(五)_Scanner类_Random类_ArrayList类
API API(Application Programming Interface),应用程序编程接口.Java API是一本程序员的字典 ,是JDK中提供给程序员使用的类的说明文档.这些类将底层的代 ...
- 很实用的h5实现名片扫描识功能快速结合市场运营
功能描述: 点击名片识别按钮,将名片上的个人信息扫描并解析出来显示. 实现步骤: 1.点击第一个页面上的名片识别按钮,调出手机摄像头和相册,让用户进行选择 2.获取照片或者图片的base64数据,传值 ...
- [JAVA]移位运算(左移<<,右移>>和无符号右移>>>)
一.背景知识 整数在内存中是以二进制的形式存在的,而且存的是该整数的补码.最高位代表符号位,正数为0,负数为1 正数的补码是其二进制本身,负数的补码则是 符号位保持1不变,其他位按位取反再加1,+0和 ...
- WPF 2D纹理的准确映射
TextureCoordinates定义了如何将一副2D纹理映射到所建立的3D网格上,TextureCoordinates为Positions集合中的每一个3D顶点提供了一个2D顶点. 映射时方向确定 ...
- 2018年BRATS 肿瘤分割挑战赛第三名分割方案One-pass Multi-task Networks with Cross-task Guided Attention for Brain Tumor Segmentation
首先说一下我对这个方案的看法,相比第一名与第二名的方案,这个方案的分割方法确实复杂的多,原论文是发表在MICCAI,后来砖投到IEEE image processing(SCI 1区),总体感觉给人一 ...
- 题解:2018级算法第二次上机 Zexal的排座位
题目描述: 样例: 实现解释: 一道看似复杂但实际既是斐波那契变形的题目 知识点:递推,斐波那契 通过问题的描述,可以得到以下规律:(除了座位数为一时)男生坐最后时,倒数第二个一定是女生:女生坐最后, ...
- 【JVM】或许,这就是二进制Class吧
水稻:看你研究盯着这个文档一天了,什么玩意让人心驰神往 菜瓜:前几天意外得到一本武功秘籍<jvms8>,看起来就情不自禁 水稻:这不是Java虚拟机的说明文档吗<PS:投来惊吓的目光 ...
- SpringBoot2 整合JTA组件,多数据源事务管理
本文源码:GitHub·点这里 || GitEE·点这里 一.JTA组件简介 1.JTA基本概念 JTA即Java-Transaction-API,JTA允许应用程序执行分布式事务处理,即在两个或多个 ...
- REACT——虚拟DOM
深入了解虚拟DOM 实际顺序 jsx->createElemnt ->虚拟DOM(JS 对象)->真实DOM 虚拟DOM中的Diff算法 :当react查找差异的时候,就会采用dif ...
- bzoj2648SJY摆棋子&&bzoj2716[Violet 3]天使玩偶*
bzoj2648SJY摆棋子 bzoj2716[Violet 3]天使玩偶 题意: 棋盘上有n个棋子,现在有m个操作,一种是加棋子,一种是查询离某个点最近的棋子.n,m≤500000. 题解: 先将已 ...