OpenFeign原理浅析

OpenFeign原理我个人觉得是非常简单的,如果你对Spring非常了解,知道FactoryBean,以及注入bean的方式,并掌握动态代理,那么自己实现一个类似这样的Http代理客户端是一点问题也没有的!

使用流程

首先我们先过一边常规的使用流程:

1.启动类打上@EnableFeignClients注解

2.然后在调用接口上打上@FeignClient注解,接口方法就是常规Post、Get注解

3.之后在代码中依赖注入这个接口就可以像调用普通方法一样实现Http调用了

思考两个问题,一个接口没有任何实现类能发起调用吗?接口类是怎么被扫描进Bean容器中的?

原理流程

@FeignClient注解

首先我们看是怎么注入容器的,先看看@FeignClient注解,就是一个平平无奇的注解,显然是不会被Spring的扫描机制自动扫描的处理的,那么答案就应该 在@EnableFeignClients注解上了

@EnableFeignClients注解

该注解内有一个@Import注解,显然这就是我们要的,有一个FeignClientsRegistrar类,名称就看得出来是FeignClient的注册类

如果对Spring注入方式不了解的话,看看我之前写的:Bean放入容器的几种方式open in new window

FeignClientsRegistrar

他实现了ImportBeanDefinitionRegistrar接口,该接口是往Spring注册BeanDefinition的,所以我们直接去看看他实现的registerBeanDefinitions方法中注册了什么BeanDefinition

BeanDefinition是Bean的定义,在Spring的Bean生成流程中是先有BeanDefinition后有Bean,所以BeanDefinition基本可以认为是一个即将要被注入的Bean

registerBeanDefinitions方法:

扫描后遍历去注册

registerFeignClient方法:

这里就非常的明显了,最后注入了个啥?FeignClientFactoryBean!!,所以最终我们在依赖注入的时候实际上获取的是FactoryBean.getObject所产生的对象!到了这Spring的工作就已经结束了

如果对FactoryBean不了解的,建议先去了解一下

FeignClientFactoryBean

这里的后续流程其实就和Spring没啥关系了,后面就是代理类的生成过程,如果想了解feign是怎么和Ribbon、Hystrix打通的倒是可以继续往下专,这里就不再带着大家往下看了(最后给了个流程图可以自己看,最后发起调用的是RequestTemplate

不过值得一提的是Feign默认是有一个重试机制的,用的是Retry,默认是关闭,当然也可以自定义重试机制,这里可能很多人都会忽略,这段代码在(SynchronousMethodHandler

总流程图

配置项

总结

所以现在懂了吗?

  1. 通过@EnableFeignCleints触发Spring应用程序对classpath中@FeignClient修饰类的扫猫
  2. 解析到@FeignClient修饰类后,Feign框架通过扩展Spring Bean Deifinition的注册逻辑,最终注册一个FeignClientFacotoryBean进入Spring容器
  3. Spring容器在初始化其他用到@FeignClient接口的类时,获得的是FeignClientFacotryBean产生的一个代理对像Proxy.
  4. 基于java原生的动态代理机制,针对Proxy的调用,都会被统转发给Feign框架所定义的一个InvocationHandler,由该Handler完成后续的HTTP转换,发送,接收,翻译HTTP响应的工作
Last Updated: