公司使用Spring Cloud做了一个微服务的工程建设管理系统。微服务框架的好处大家都是知道的,这里就不再啰嗦。

项目越来越多,除了一些基础服务通用性较强外,发现很多业务服务都是貌似而已,同样的质量管理,项目A需要这么处理,项目B需要那么处理。我们传统搞法,肯定是在业务代码里加if-else。但是太多定制后,到处都是这样的代码,一个服务可能很多项目组都在改,这个结果可能导致相互影响,失去了微服务解耦的初衷。

那现在我们把各个业务服务的项目定制版本单独发布呢?貌似可以,但这里又出现另外一个问题:有个公用的业务服务A,需要对接多个项目定制的业务服务B\C\D。通常微服务之间的接口调用都是通过FeignClient来实现,这个技术经过了大量的实践,肯定没有啥问题。但我们不是A到B的问题,我们需要在A到B/C/D的时候,根据预先的配置,让A知道应该是调A还是B还是C。

使用FeignClient的人都知道Feign的用法,@FeignClient(name="provider", path="test")。服务名通常是写死的,那怎么来实现name的动态调整呢。

这几天看了不少人的想法:

一种是通过Feign.builder().encoder(encoder).decoder(decoder).client(feignClient).contract(contract).target(ISpecailRouterClient.class, url)这种方式来调整目标,参考https://baijiahao.baidu.com/s?id=1633128626497116063&wfr=spider&for=pc。

一种是直接注入Feign的实现,类似HystrixFeign,参考https://blog.csdn.net/zhouhao88410234/article/details/99982043,看着也能实现,但过于复杂。

看了半天,还是决定自己从Feign的源码看起,看怎么搞更加方便。

看到RequestInterceptor,眼前一亮,对啊,拦截器这么好用的东西为什么不用呢。仔细一看接口中的RequestTemplate参数,一切事情就很简单了。下面列几个方法,大家就知道怎么玩了。

1、RequestTemplate.feignTarget().name()获得FeignClient注解中的name

2、RequestTemplate.queries()获取请求参数

3、RequestTemplate.url()获取访问的全路径地址(含参数)

4、RequestTemplate.path()获取访问的全路径地址(不含参数)

5、RequestTemplate.target(String target)设置服务的地址(全路径),或RequestTemplate feignTarget(Target<?> feignTarget)

于是自建一个拦截器,即可实现所有FeignClient的请求拦截,并根据需要去改变目标服务。如下:

@Servicepublic class MyInterceptor implements RequestInterceptor {private static Map<String, String> routerMap = new HashMap<String, String>();public void apply(RequestTemplate template) {template.header("Content-Type", "application/json");String serviceName = template.feignTarget().name();Map<String, Collection<String>> map = template.queries();//根据请求参数进行路由获取,这个配置可以自己决定放在什么地方String target = routerMap.get(map.get("projectId").toArray()[0]+":"+serviceName);if (target != null) {template.target(target);}System.out.println("这是自定义请求拦截器,"+template.path());}

上述是对微服务中的所有Feign请求进行统一拦截,因为他注册成了全局的拦截器。如果只需要对某些FeignClient生效,可以见到改造一下

1、先去掉@Service

2、创建一个Config类

public class MyFeignConfig {@Beanpublic RequestInterceptor myRequestInterceptor(){return new MyInterceptor();}}

3、修改FeignClient的声明:

@FeignClient(name="provider", path="test", configuration = MyFeignConfig.class)

相信不用多说,大家都清楚了。

总结一下:要想用的好,还是要多看源码。

基于拦截器实现FeignClient的动态路由相关推荐

  1. JWT的API鉴权,基于拦截器的token与鉴权

    基于JWT的API鉴权 基于拦截器的token与鉴权 如果我们每个方法都去写一段代码,冗余度太高,不利于维护,那如何做使我们的代码看起来更清爽呢?我们可以  将这段代码放入拦截器去实现 Spring中 ...

  2. 基于拦截器实现防表单重复提交

    1.定义自定义注解 2.定义防重复提交拦截器 /*** 防止重复提交拦截器** */ @Component public abstract class RepeatSubmitInterceptor ...

  3. 基于jwt的用户鉴权:拦截器概述

    基于拦截器的token与鉴权 如果我们每个方法都去写一段代码,冗余度太高,不利于维护,那如何做使我们的代码看起来更清爽呢?我们可以将这段代码放入拦截器去实现 Spring中的拦截器 Spring为我们 ...

  4. Vue2学习小记-给Vue2路由导航钩子和axios拦截器做个封装

    1.写在前面 最近在学习Vue2,遇到有些页面请求数据需要用户登录权限.服务器响应不符预期的问题,但是总不能每个页面都做单独处理吧,于是想到axios提供了拦截器这个好东西,再于是就出现了本文. 2. ...

  5. struts2拦截器的实现原理及源码剖析

    拦截器(interceptor)是Struts2最强大的特性之一,也可以说是struts2的核心,拦截器可以让你在Action和result被执行之前或之后进行一些处理.同时,拦截器也可以让你将通用的 ...

  6. ejb 示例 2018_Java EE EJB拦截器教程和示例

    ejb 示例 2018 在此示例中,我们将看到如何在EJB中使用拦截器并使用简单的Web应用程序对其进行测试. 1.简介 顾名思义,当您想拦截对EJB方法的调用时,将使用拦截器. 如果为Bean声明一 ...

  7. Java EE EJB拦截器教程和示例

    在此示例中,我们将看到如何在EJB中使用拦截器并使用简单的Web应用程序对其进行测试. 1.简介 顾名思义,当您想拦截对EJB方法的调用时,将使用拦截器. 如果为Bean声明一个拦截器,则每次调用该B ...

  8. SpringCloud微服务Zuul网关动态路由

    SpringCloud微服务Zuul网关动态路由 zuul动态路由 1. 网关层动态配置路由映射规则 2. 将同一个请求根据自定义的规则,路由到不同服务中 FeignClient动态请求 实现功能 实 ...

  9. 动态路由和动态路由中的RIP协议

    动态路由和动态路由中的RIP协议 一.动态路由 1.动态路由的特点 2.选择依据:度量值 3.收敛 4.静态路由与动态路由的比较 二.动态路由协议分类 三.RIP是距离矢量路由选择协议 1.RIP的基 ...

最新文章

  1. java static method_java static关键字静态方法详解,静态方法实例分享
  2. 个人易遗忘的代码记录(6) 汉字转拼音
  3. 为什么不敢和别人竞争_内心很脆弱,不敢和人竞争。该怎么办?
  4. Mac下安装caffe(cpu-only)
  5. iframe弹出层中关闭包含iframe的div(子页面调用父页面js函数)
  6. 04.electron-(使用remove模块及安全策略)
  7. yosemite java 6_Mac OS X Yosemite 安装Java6
  8. fastDFS 无法获取服务端连接资源:找不到可用的tracker
  9. [下载]最新QQ空间牧场开通器 V2.0
  10. 抠图软件哪个好?这些软件值得收藏
  11. Prometheus - 普罗米修斯 - 日志监控mtail尝试
  12. 基于Verilog HDL的数字秒表
  13. 从语义网络到知识图谱
  14. ASP.NET页面统一布局、页面导航(站点地图)
  15. 哪个软件测试手机电池续航好,6款手机电池续航测试排名:iPhone12mini险些垫底,第1名是小米10...
  16. 算法分析与设计(一)——0-1背包问题
  17. java如何解压rar文件怎么打开,Java压缩与解压rar文件
  18. python-画3D图
  19. 前端权限管理方案之精确到按钮级别
  20. 服务器如何设置防火墙?

热门文章

  1. Windows下QtCreator不能切换中文输入法
  2. 基于ffmpeg与nvidia-video-sdk-8.1.24视频硬解与软解多路rtsp,支持Qt的QOpenglWidget与qml接口显示
  3. 使用Cheat Engine与DnSpy破解Unity游戏
  4. HTTP跳槽涨薪篇,通俗易懂~
  5. 10款超好用的矢量图软件,轻松绘制矢量图
  6. HTML+CSS(详细版)
  7. 【python第四章——序列(列表、元组、字典、集合、字符串、正则)】
  8. 1-6 集合\第7节 Collections工具类\第8节 Map集合
  9. Java多态之“编译看左边,运行看右边”
  10. linux中的likely和unlikely