openfegin调用

为什么要用fengin?
Feign 就是来简化我们发起远程调用的代码的,那简化到什么程度呢?简化成就像调用本地方法那样简单。
在这里插入图片描述

opengin如何使用?
先定义一个接口:
在这里插入图片描述
第二步:

@EnableFeignClients(basePackages = "com..*)

第三步:服务定义一个方法,其方法路径服务中的接口 URL 地址一致即可。
在这里插入图片描述
第四步 服务的 POM 文件中引入 OpenFeign 组件。

第五步:直接调用

@Autowired
    private RemoteUserService remoteUserService;
 
R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER)

加了 @FeignClient 注解的接口后,我们就可以调用它定义的接口,然后就可以调用到远程服务了。

核心流程:
在这里插入图片描述
OpeFeign 包扫描原理:
我们需要在程序启动处添加@EnableFeignClients注解,该注解会导入FeignClientsRegistrar类进入到spring容器中,该类实现了ImportBeanDefinitionRegistrar接口,在spring启动的过程中会调用FeignClientsRegistrar中实现的registerBeanDefinitions,,那我们就去看下FeignClientsRegistrar#registerBeanDefinitions方法。
上源码:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第一部分是为了找到@Feignclient标识的接口类,第二部分就是对找出的接口类进行处理了处理,主要关注registerClientConfiguration和registerFeignClient函数。

其中registerClientConfiguration是为了处理@FeignClient#configuration属性的,在这个函数会往spirng容器中添加#{serviceName}.FeignClientSpecification作为名字的FeignClientSpecification类对象

registerFeignClient函数:
在这里插入图片描述
在这里插入图片描述
上面截图的就是OpenFeign对于接口的动态实现。这时候可能会有同学问,什么,真的么,factoryBean是啥东东,这代码里我没有看到半点动态代理的影子。

确实在上面我们只看到factoryBean的组装过程,我们看到往factoryBean中塞了好多属性,只有最后调用了factoryBean.getObject()产生了BeanDefinitionBuilder对象,这个对象说的是OpenFeign对于接口的动态实现类。那么我们就一起来看下factoryBean是个神马东西,
在这里插入图片描述
经过分析是jdk的动态代理实现:
在这里插入图片描述
总结:
在这里插入图片描述
调用具体实现:
feign.SynchronousMethodHandler#invoke
在这里插入图片描述
feign.SynchronousMethodHandler#executeAndDecode
在这里插入图片描述
代码上说明的就是如果配置了decode对象,那么直接用decode去解码reponse,如果没有配置,则使用AsyncResponseHandler#handleResponse方法去处理reponse,那么首先这个deocde是在哪里配置的呢?经过我代码搜寻,发现了这个是创建SynchronousMethodHandler对象时传入的forceDecoding参数来控制的,具体截图就不放了,大家可以自己去找下,并且这forceDecoding默认值是false,也就是说,一般情况下处理reponse的方式都是走的AsyncResponseHandler#handleResponse方法,这个方法里就有OpenFeign对于response的各种处理。

最后大家可能会有疑问,哇,这个处理reponse的AsyncResponseHandler,看这个名字是异步的呀,那OpenFeign难道也是异步返回结果的么?答案是否定的,具体我们来看下代码
在这里插入图片描述

这边也是第三部分的代码截图,只是上面最后的一丢丢截图截不下了,可以看到,这边最后是调用了CompleteFuture#join方法,这个方法会堵塞主线程,直到resultFuture结果返回,也就是说处理reponse的过程是异步的,但是返回结果还是同步的,在最后结果处理结束之前,主线程都是堵塞的。

负载均衡实现
构造
FeignBlockingLoadBalancerClient传入了负载均衡客户端LoadBalancerClient及负载均衡客户端工厂LoadBalancerClientFactory该工厂是用来创建每一个Feign客户端对应的子容器
AnnotationConfigApplicationContext及从对应子容器获取相应的Bean实例对象,如:Client,Request.Options,Logger.Level等。

在这里插入图片描述

扩展链路追踪实现:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这段代码就是创建了一个RequestInterceptor对象,他的作用就是我们在使用OpenFeign调用时往http请求的head上添加traceId,方便我们进行链式追踪。

总结
本文通过我的开源项目 PassJava 中用到的 OpenFeign 作为示例代码作为入口进行讲解。然后以图解+解读源码的方式深入剖析了 OpenFeign 的运行机制和架构设计。

核心思想:

OpenFeign 会扫描带有 @FeignClient 注解的接口,然后为其生成一个动态代理。

动态代理里面包含有接口方法的 MethodHandler,MethodHandler 里面又包含经过 MVC Contract 解析注解后的元数据。

发起请求时,MethodHandler 会生成一个 Request。

负载均衡器 Ribbon 会从服务列表中选取一个 Server,拿到对应的 IP 地址后,拼接成最后的 URL,就可以发起远程服务调用了。

在这里插入图片描述
面试题:
补充说明: Feign的底层用的是Ribbon,但超时时间以Feign配置为准
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值