Feign简介
在上一篇文章中分析了Eureka
的注册、续约、服务剔除、服务自我保护等机制,地址在https://blog.csdn.net/lgq2626/article/details/80288992 。这篇分析SpringCloud
的feign
。SpringCloud
微服务项目之间调用是通过httprest请求来进行服务调用的,之前我们会用到HttpClient
等工具来进行服务请求,Spring
对这种请求进行了处理,封装成了可声明式的web
客户端,使得编写web客户端更容易,feign
还支持可插拔的编码器和解码器,Spring
在用的时候增加了对@requestMapping
的处理,同时,SpringCloud
还对feign
集成了注册中心(eureka)
和客户端负载均衡(ribbon)
,使得我们拥有一个客户端负载均衡的web
请求客户端。
Feign在项目中的配置和使用
在Springcloud中使用feign的时候,需要在配置类中加入一个@EnableFeignClients注解。代码如下:
1 | //springboot 启动类 |
配置feign调用客户端
1 | "xxx-server",configuration = FeignConfiguration.class) (value = |
经过上面的配置,直接在项目里面注入容器调用接口就可以了。
Feign源码分析
在@EnableFeignClients
标签中,import
了一个FeignClientsRegistrar
类,那么这个FeignClientsRegistrar#registerBeanDefinitions()
在什么时候调用的呢?跟着Spring
的源码走下去,看过源码的人都会直接看到AbstractApplicationContext#refresh()
方法,整体整理一下代码:
1 |
|
根据上面整理的代码发现,FeignClientsRegistrar#registerBeanDefinitions()
方法是在扫描完bean
之后,只放了一个beanname
的情况下, 并没有进行IOC
注册的时候调用的,这就是Spring
动态扩展Bean
,实现BeanDefinitionRegistryPostProcessor
接口的所有方法也会在这里调用下postProcessBeanDefinitionRegistry()
方法。关于Spring
的东西就分析到这里。下面回到正题,分析FeignClientsRegistrar#registerBeanDefinitions()
方法:
1 |
|
读过Dubbo源码的同学都知道,当在DubboNamespaceHandler
中解析reference
标签的时候,传入了一个ReferenceBean
对象,把xml
中配置的属性都塞到这个对象上,也是装到了beanDefinitionNames
中,然后发现ReferenceBean
类和FeignClientFactoryBean
都实现了FactoryBean
的接口,并且里面都有getObject()
和getObjectType()
方法。当接口调用到这个feign
客户端的时候,会从IOC
中读取这个FeignClientFactoryBean
并且调用getObject
方法。下面就是分析getObject
方法:
1 |
|
首先看配置了url
的,指定了url
的feignclient
解析,一直跟着代码跟到了Feign.Builder#target()
方法:
1 | public <T> T target(Target<T> target) { |
直接看ReflectiveFeign#newInstance()
方法:
1 | //ReflectiveFeign#newInstance() |
Feign源码总结
从读取注解到注入IOC容器,再到编码参数,发起请求,解码结果,整个封装过程都对我们开发带来了极大得便利,此文只是分析了feign带有url参数得解析方式,集成eureka和ribbon的在https://blog.csdn.net/lgq2626/article/details/80481514中做了分析。下面流程图总结下流程:
参考地址
如果大家喜欢我的文章,可以关注个人订阅号。欢迎随时留言、交流。如果想加入微信群的话一起讨论的话,请加管理员简栈文化-小助手(lastpass4u),他会拉你们进群。