Feign 调用前所进行的操作:
1.添加了 Spring Cloud OpenFeign 的依赖
2.在 SpringBoot 启动类上添加了注解 @EnableFeignCleints
3.按照 Feign 的规则定义接口 , 添加@FeignClient 注解
4.在需要使用 Feign 接口的地方, 直接利用@Autowired 进行注入
5.使用接口完成对服务端的调用
可以根据上面使用 Feign 的步骤大致猜测出整体的工作流程:
SpringBoot 应用启动时, 由针对 @EnableFeignClient 这一注解的处理逻辑触发程序扫描 classPath中所有被@FeignClient 注解的类, 将这些类解析为 BeanDefinition 注册到 Spring 容器中
Sping 容器在为某些用的 Feign 接口的 Bean 注入时, Spring会尝试从容器中查找实现类。
由于我们从来没有编写过实现类, 上面步骤获取到的实现类必然是 feign 框架通过扩展 spring 的 Bean 处理逻辑, 创建一个动态接口代理对象, 这里我们将其注册到spring 容器中。
Spring 最终在使用到接口的 Bean 中注入了实例。
当业务请求真实发生时, 对于接口的调用被统一转发到了由 Feign 框架实现的 InvocationHandler 中, InvocationHandler 负责将接口中的入参转换为 HTTP 的形式, 发到服务端, 最后再解析 HTTP 响应, 将结果转换为 Java 对象, 予以返回。
上面整个流程可以进一步简化理解为:
我们定义的接口由于添加了注解 @FeignClient, 最终产生了一个虚假的实现类代理
使用这个接口的地方, 最终拿到的都是一个假的代理实现类。
所有发生在 DemoServiceProxy 上的调用, 都被转交给 Feign 框架, 翻译成 HTTP 的形式发送出去, 并得到返回结果, 再翻译回接口定义的返回值形式。
所以不难发现, Feign 的核心实现原理就是java 原生支持的基于接口的动态代理