前言

最近准备将公司的一个核心业务系统用 Java 进行重构,大半年没写 JavaJDK 都更新到 14 了,考虑到稳定性等问题最终还是选择的 JDK11

在整体架构选型时,由于是一个全新的系统,所以没有历史包袱,同时团队中也有多位大牛坐镇,因此我们的选项便大胆起来。

最终结果就是直接一把梭,直接上未来的大趋势:Service Mesh,直接把什么 SpringCloudDubbo 这类分布式框架全部干掉。

本次的重点不是讨论 Service Mesh 是什么、能解决什么问题、为什么选择它,毕竟我也在学习阶段,啥时候整明白线上也稳定了再和大家来交流。

问题

既然方向定了就开始实际撸码了,不过刚一开始就验证了”理想很丰满、现实很骨感“;

由于我们去掉了 SpringCloudDubbo 这类框架,服务的注册、发现、负载均衡等需求全部都下沉到 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 请求的细节屏蔽掉。

当然也适合公司内部之间的服务调用,和咱们以前写 SpringCloudDubbo 时类似;服务提供方提供一个 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 增强包的更多相关文章

  1. 撸了一个 Feign 增强包 V2.0 升级版

    前言 大概在两年前我写过一篇 撸了一个 Feign 增强包,当时准备是利用 SpringBoot + K8s 构建应用,这个库可以类似于 SpringCloud 那样结合 SpringBoot 使用声 ...

  2. virtualbox安装增强包及配置共享文件夹

       因为需要在host及虚拟机间传输数据,想使用共享文件夹.但是单独设置了共享文件夹后在centos里找不到共享文件夹,看了下要安装增强包.好吧,顺 便也解决下鼠标切换的问题,省的老是按右CTL切换 ...

  3. 【转】virtualbox安装增强包及配置共享文件夹

    原文网址:http://www.2cto.com/os/201308/233609.html virtualbox安装增强包及配置共享文件夹     因为需要在host及虚拟机间传输数据,想使用共享文 ...

  4. 虚拟机 minimal 安装增强包

    在虚拟机下安装了一个centos的minimal镜像,发现增强包不能安装,鼠标不能在虚拟机和物理机间自由切换.不能共享粘贴板,非常是不爽,这里摸索出在centos  minimal OS下安装增强包的 ...

  5. VirtualBox安装增强包实现文件共享

    环境: win10 64位 Virtualbox 5.1.30 ubuntu-16.04.3-server-amd64.iso 1. 安装好ubuntu后,打开virtualbox安装路径文件夹,找到 ...

  6. virtualbox中新版本Ubuntu安装软件增强包后重启无限登录界面的解决办法

    原来我虚拟机版本是4.2.10,装的Ubuntu3.3,因为版本过老使用出现了一些问题,于是换成14.04,安装成功,但是装增强包的时候,装完重启,无限登录界面,密码是对的. 看了网上的很多方法,什么 ...

  7. 使用Dockerfile创建一个tomcat镜像,并运行一个简单war包

    docker已经看了有一段时间了,对镜像和容器也有了一个大致了解,参考书上的例子制作一个tomcat镜像,并简单运行一个HelloWorld.war 1.首先下载linux环境的tomcat和jdk, ...

  8. 创建你的第一个Composer/Packagist包

    今天我们要介绍一下如何通过Composer和Packagist向PHP社区贡献代码包.首先,如果你是一个PHP开发者但是还不知道什么是Composer,请先参考了一下这篇文章http://docs.p ...

  9. python 如何编写一个自己的包

    python 如何编写一个自己的包 先写function 内容 package/wadepypk$ ls __init__.py f1.py f2.py f1.py def show(): print ...

随机推荐

  1. CSDN首页

    打开CSDN首页,大部分的内容都是——AI,大数据,Python,很少谈及C#,谈到了也是拿C#做反面对比.博客园的首页没有这种恶意诋毁的言论,什么都有,.net的文章也很多,你发你的大数据和AI,我 ...

  2. linux系统配置常用命令top

    本人测试系统:centos7 命令名称:top Linux top命令用于实时显示 process 的动态. 参数:-b 批处理 -c 显示完整的治命令 -I 忽略失效过程 -s 保密模式 -S 累积 ...

  3. Spreading the Wealth,思维

    题目去洛谷 题意: 很清晰,n个人,每人有一些硬币硬币总数sum≡0(mod n),通过一些互相交换,使硬币数平均(即每人有相同个数的硬币) 分析: 还是有点思维含量的,我们这样想,我们其实就是要确定 ...

  4. C# 爬取猫眼电影数据

    最近做了一个新项目,因为项目需要大量电影数据,猫眼电影又恰好有足够的数据,就上猫眼爬数据了. 1.先分析一下网页地址,发现电影都是被排好序号了,这就很简单了. 2.在分析页面,这次主要爬取黄色框中的内 ...

  5. 一个简单的webAPI调用

    1.新建一个ASP.NET Web应用程序. 2.选择空模板,WebAPI. 3.在Models文件夹添加Product类. 4.添加空控制器ProductController. 5.ProductC ...

  6. LintCode笔记 - 145.大小写转换 - 极简之道 - 最短代码

    这道题目一眼就能看出是送分题,当然在这里也不谈高难度的实现逻辑,肯定有同学会想直接用自带函数实现不就可以了吗? 对的,就是这么简单,然而今天的重点是如何把代码简写到最短. 本文章将带你把代码长度从 一 ...

  7. [HCTF 2018]admin

    前言: 最近在BUUCTF刷题,参照师傅们wp后复现一下 0x01 拿到题目后进去如下界面 发现有登录和注册界面,相比是要登录后才能查看想要的信息. 查看页面源代码,看看有没有上面提示,界面如下 提示 ...

  8. VulnHub::DC-1

    实验环境 一共有五个flag,有多种方法去提权,我们最终目标是去拿到/root的flag.总的来说,难度不高,适合新人练手 渗透过程 0x01 信息搜集 由于不知道靶机IP地址,进行D段扫描,获得靶机 ...

  9. HTB::OpenAdmin

    实验环境 渗透过程 0x01 信息搜集 sudo nmap -sS -p1-10000 -sV -sC -T4 10.10.10.171 开放了22(SSH)端口和80(HTTP)端口 访问80端口, ...

  10. element-ui(vue版)使用switch时change回调函数中的形参传值问题

    需求说明 有多个switch组件 需要知道switch的状态 表格中当前行(scope.row)的数据 问题描述 官方文档中对switch中change的描述: 目前能得到switch的状态值,但是无 ...