问题:
1.@FeignClient怎么解析的。
2.@FeignClient标注的接口放到spring容器里存的是什么。
3.调用@FeignClien接口的方法是怎么执行的。
1.@FeignClient怎么解析的?
首先从@EnableFeignClients入手,这个注解里面引入了FeignClientsRegistrar,这个类实现了ImportBeanDefinitionRegistrar,ImportBeanDefinitionRegistrar这个类主要是注册bean到spring容器的,所以到这里,大概猜测是解析@feignClient接口的类后,把解析的结果注册到spring容器。按照这个猜想继续往下看。
走到registerBeanDefinitions方法,有两个方法registerDefaultConfiguration,registerFeignClients。registerDefaultConfiguration主要干的事情是:如果@EnableFeignClients注解中的defaultConfiguration不为空,则注入到spring容器中。而registerFeignClients方法则是注入FeignClient的地方。
进入registerFeignClients,这里会扫描@EnableFeignClients所在类的包及其子包下的标记了@FeignClient类,调用registerFeignClient方法,将被@rFeignClient标注的接口注入到IOC容器中,注入的是FeignClientFactoryBean
2.@FeignClient注解的接口放到spring容器里存的是什么?
@FeignClient注解的接口放到spring容器是一个FeignClientFactoryBean,但在用@Autowired注入需要实例化的地方,spring在启动时,会调用FactoryBean的getObject方法,getObject方法主要是生成动态代理类:
从Spring上下文中,获取FeignContext这个Bean,这个bean是在哪里注册的呢?是在FeignAutoConfiguration中注册的。 然后判断url属性是否为空,如果不为空,则生成默认的代理类;如果为空,则走负载均衡,生成带有负载均衡的代理类。那么重点关注loadBalance方法。
feignClient创建一个子上下文,然后存入以contextId为key的map中(NamedContextFactory的getContext方法)。此处会返回LoadBalancerFeignClient这个Client。FeignRibbonClientAutoConfiguration会导入相关配置类。 然后会从子上下文中,查找Targeter bean,默认返回的是DefaultTargeter, 最后调用target方法。
所以在@Autowired注入的时候,是注入的标记@FeignClient接口的动态代理类。当在自己的业务类中调用feign接口方法时,会调用FeignInvocationHandler的invoke方法。
3.那注入完成后,OpenFeign远程调用是怎样的呢?
从初始化的流程来看 feign.MethodHandler是feign.SynchronousMethodHandler,而java.lang.reflect.InvocationHandler是feign.ReflectiveFeign.FeignInvocationHandler,然后在调用方法时 首先要进入的就是feign.ReflectiveFeign.FeignInvocationHandler#invoke
下面的代码中有一个 executeAndDecode()方法,该方法通过RequestTemplate生成Request请求对象,然后利用Http Client(默认)获取response,来获取响应信息
client.execute(request, options),默认使用HttpURLConnection发起远程调用,这里的client为LoadBalancerFeignClient。看他的execute方法,最终是通过Ribbon负载均衡器发起远程调用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用