Feign总结
2021-07-05 12:54:34 1 举报
feign的核心源码分析,欢迎指正
作者其他创作
大纲/内容
SynchronousMethodHandler#executeAndDecode
将这批方法跟target一起生成一个FeignInvocationHandler代理类
AbstractLoadBalancerAwareClient#executeWithLoadBalancer()
创建一个Observable
command
SynchronousMethodHandler
是否抛错
否
创建Feign的上下文,将FeignClientsConfiguration及配置类feign注解的类封装在这里
InvocationHandlerFactory.Default#create
根据方法参数GET /user/{id} HTTP/1.1创建
获取client
clientFactory
2
执行请求逻辑
@Import(FeignClientsRegistrar.class)
获取targeter
用户发起调用
处理响应
FeignClientsRegistrar#registerFeignClients
最终来到
BuildTemplateByResolvingArgs#resolve
Request
feign.Client.Default#execute
FeignClientFactoryBean#configureFeign
1
是
Feign.Builder
FeignClientsRegistrar的scanner
是否大于最大重试次数
operation.call(server).doOnEach(new Observer<T>()会走onComplete、onError、onNext
2 真实逻辑执行
ClassPathScanningCandidateComponentProvider#findCandidateComponents
重试,这里会有时间间隔判断
创建一个LoadBalancerCommand这里定义了重试的handler
SynchronousMethodHandler#targetRequest
创建feign
封装方法参数
解析成本地urlhttp://localhost:8010/user/1
dispatch.get(method).invoke(args)
看EnableFeignClients是否配置了basePackages没有则获取EnableFeignClients所在类的包路径
真正执行FeignLoadBalancer#execute
将FeignClient的属性跟ServiceAClient封装在一个holder(FeignClientFactoryBean)中并以alias = ServiceAFeignClient,className = com.zhss.ServiceAClient封装在spring容器中
HystrixTargeter
将ServiceA/user/1补全http为http://ServiceA/user/1
cachingFactory
ReflectiveFeign#newInstance
AutoConfigureBefore
@EnableFeignClients
FeignClientsRegistrar#registerClientConfiguration
BuildTemplateByResolvingArgs#create
根据方法名获取一个SynchronousMethodHandler然后走里面的逻辑
varBuilder{\"id\" : 1}
catch逻辑AbstractLoadBalancerAwareClient#107return Observable.error(e);
input.request()
server
此处为获取eureka client下的注册实例参考ribbon下的逻辑
这里会生成feign对应的ILoadbalancerZoomAwareLoadBalancer
ServiceAClient.createUser
new HardCodedTarget<>
FeignClientsRegistrar#registerDefaultConfiguration
CachingSpringLoadBalancerFactory
LoadBalancerFeignClient#lbClient
FeignClientsConfiguration#feignRetryer
生成一个request
将配置的configuration以default.com.zhss.ServiceBpplication.FeignClientSpecification的名称注册到容器中
selectServer()
Feign.Builder#build
FeignClient是否配置了url
这里主要是将basePackages转为真是路径,并扫描该路径下所有使用了FeignClient注解的类classpath*:com/zhss/**/*.class
SynchronousMethodHandler#invoke
获取默认的属性defaultAttrs
是,重试逻辑
FeignLoadBalancer#execute
将url和服务名称ServiceA组合成http://ServiceA
FeignAutoConfiguration#feignContext
throw e
response
feign.Client.Default#convertResponse
生成LoadBalancerCommand
spring容器实例化
DefaultFeignLoadBalancedConfiguration#feignClient(LoadBalancerFeignClient)
FeignClientFactoryBean#loadBalance
FeignClientsConfiguration#feignDecoder(SpringDecoder)
FeignClientsRegistrar#getBasePackages
封装response返回
contract.parseAndValidatateMetadata
LoadBalancerContext#reconstructURIWithServer
HystrixTargeter#target
FeignClientsRegistrar#registerFeignClient
Feign的配置加载
生成一批接口handler
该类是跟eureka client交互的类
ServerOperation#call
获取到目标类的方法定义,例如:方法名,参数,返回值、GET/POST等ServiceAClient#deleteUser(Long)
SynchronousMethodHandler#decode
FeignClientFactoryBean#feign
server是否为空
SynchronousMethodHandler#invoke中的catch走重试逻辑
FeignRibbonClientAutoConfiguration
retryer.continueOrPropagate(e)
默认超时时间读取都是1s
FeignClientFactoryBean#getObject
serverList
targetToHandlersByName.apply(target)
FeignClientsConfiguration#feignContract(SpringMvcContract)
取出配置的服务名称ServiceA
FeignClientsConfiguration#feignLoggerFactory(DefaultFeignLoggerFactory)
ServiceAClient.deleteUser
eureka client
AbstractLoadBalancerAwareClient#buildLoadBalancerCommand
HardCodedTarget#apply
返回 server
ServiceAClient.updateUser
FeignInvocationHandler#invoke
创建一个command
将varBuilder编码encodeValueIfNotEncoded
RequestTemplate#expand将url和参数绑定/user/1
获取一个RetryHandler
将配置的configuration以ServiceA.FeignClientSpecification的名称注册到容器中
获取FeignClient里的所有属性attributes
RequestTemplate
LoadBalancerCommand#313x.Observer#onError
LoadBalancerFeignClient#execute
command.submit()
创建一个Requesttemplate并将参数与url解析绑定
3 响应解码
ILoadBalancer
执行出错
配置
ServiceAClient.sayHello
0 条评论
下一页