这是我参与更文挑战的第7天,活动详情查看: 更文挑战
总文档 :文章目录
Github : github.com/black-ant
一 . 前言
前面一篇说了Feign 的初始化配置 , 这一篇来说说 FeingBean 的加载 :
接上一篇中 , FeignClient 被扫描处理 , 加入 Bean 工厂中
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
那么后续是如何使用的呢?
二 . FeignBean 的创建
Bean 的创建主要是基于 FeignClientFactoryBean , 通过工厂实现具体的 FeignBean 个体 ,后续接口代理的时候 , 会反射到该类
2.1 发起的原因
- Step 1 : Spring 加载一个 Bean ,发现 Bean 中有一个 Autowired 标注的对象
- Step 2 : 通过 AbstractBeanFactory getBean 获取这对象
- Step 3 : getSingleton 查询到对应的 工厂方法 (FeignClientFactoryBean)
- Step 4 : 调用 FeignClientFactoryBean # getObject 获取对象
- Step 5 : ReflectiveFeign 初始化绑定对象 (newInstance)
- Step 5.1 : ReflectiveFeign.apply(Target target) 对 Method 进行处理
- Step 5.1 : ReflectiveFeign.apply(Target target) 对 Method 进行处理
简单点说 ,当出现 Autowired 注入 FeginClient 的时候 , 会通过 FeignClientFactoryBean 返回一个代理类
2.2 调用的流程
前置知识点 : FactoryBean 发起 Object 的获取
PS : IOC 容器中会构建 FactoryBean , 在需要实现 Object 的时候 , 调用 FactoryBean 的 getObject 方法获取具体的Object 对象
1 | java复制代码C07- FactoryBean |
扩展 :
了解过 IOC 流程的应该会比较清楚 , 这里简单点说就是提供一个方法 ,让 IOC 获取 FactoryBean 需要创建的类的实例 (即从 FactoryBean 获取它工厂处理出来的对象)
相关逻辑可以从 DefaultSingletonBeanRegistry # getSingleton 方法中看到
1 | java复制代码com.gang.cloud.template.demo.client.SampleFeignClient |
Step 1 : FeignClientFactoryBean 调用主流程
主调流程为 :
- FeignClientFactoryBean.getObject
- FeignClientFactoryBean.getTarget
- FeignClientFactoryBean.loadBalance
- HystrixTargeter.target
- ReflectiveFeign.newInstance :
这里看到 , 这里的起点是 getObject , 该方法是一个重写方法 , 源头为接口 FactoryBean < Object >
1 | java复制代码C09- FeignClientFactoryBean |
[Pro0001] : FeignContext 的作用 ?
创建虚类实例的工厂。它为每个客户端名称创建一个Spring ApplicationContext,并从中提取所需的bean.
[Pro0002] : Feign.Builder ?
这是一个 feign 构造工具 , 包含常用的配置信息和工具对象 , 例如最常见的 client 和 加密解密工具 ,
可以理解为一个集合体
1 | java复制代码public static class Builder { |
Step 2 : loadBalance 构建
1 | java复制代码C09- FeignClientFactoryBean |
[Pro] : getOptional 获取 Client
此处会根据我们之前初始化中说的 , 通过配置选择是否调用 OkHttpClient 或者 HttpClient , 配置后就会发现 , 实际上进入了如下类 :
1 | java复制代码C- OkHttpFeignConfiguration |
Step 3 : HystrixTargeter 的处理
因为之前的 Feign 就行 HystrixFeign ,所以通常这里会直接调用 feign.target(target);
1 | java复制代码public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign, |
PS : 如果不是 HystrixFeign , 后续其实还是创建了一个 HystrixFeign
Step 4 : Invoke 代理类的构建
1 | java复制代码C30- ReflectiveFeign |
PS:M30_01_01 元数据集合
PS:M30_01_02 BuildTemplateByResolvingArgs 对象
PS:M30_01_03 MethodHandler 对象参数
可以看到 , 相关的参数均在里面了
总结
这一部分也不麻烦 ,总得来说就是生成了一个 Proxy ,对接口进行了代理
本文转载自: 掘金