Spring Boot Feign 使用与源码学习
Feign 的使用
单体服务拆分微服务后,在一个服务中会经常需要调用到另外的服务。这种情况,除了使用 Dubbo 等 RPC 框架外,最简单的方法是通过 Spring Cloud Feign 来进行服务间的调用。
Feign 是通过代理使用 Http 请求服务返回编码后的内容。使用 Feign 可以通过简单的申明去除手动发起 Http 和编解码等复杂过程。
先看看 如何简单的使用 Feign。
首先引入 `spring-cloud-dependencies` 和 `spring-cloud-starter-openfeign`
启动类上添加注解 `@EnableFeignClients`
定义 Client 类
使用 Client 类调用远程服务,这样调用使逻辑看上去是在面向对象编程,而不用再去手动处理 Http 请求。
Feign 源码解读
从项目启动、获取 Client 实例、实际方法调用 3 个过程分析 Feign 相关源码。
启动
spring-cloud-openfeign-core 包中通过 SPI 机制,运行 FeignAutoConfiguration 文件。根据配置生成 `org.springframework.cloud.openfeign.FeignContext`、`feign.Client`、`org.springframework.cloud.openfeign.Targeter` 3 个主要的类
`@EnableFeignClients` 注解中通过 `@Import` 导入 FeignClientsRegistrar.class 类,在类中注册 FeigntClient 的默认配置和扫描并注册 Client 类到容器中。
FeignClientsRegistrar 类解读
获取 Client 实例
根据启动时注入的内容可知, 从容器获得 client 的实例是通过 FeignClientFactoryBean 类的 getObject() 方法获取。
最终得到的是一个 Proxy 代理,实例化过程见下图:
FeignContext、HystrixTargeter 都是启动的时候生成到容器的 Bean
Feign.Builder 是 Feign Client 的构建者
SynchronousMethodHandler.Factory 是 Client 中定义的方法拦截器的创建工厂,Client 中每个方法对应一个 SynchronousMethodHandler 处理器
ReflectiveFeign.ParseHandlersByName 将 Client 中的方法名解析得到不同的 SynchronousMethodHandler
ReflectiveFeign 是 Feign 类的唯一实现
InvocationHandlerFactory.Default 方法处理创建工厂的默认实现,生成代理类方法的处理实现
ReflectiveFeign.FeignInvocationHandler 代理类方法处理的默认类,是代理类拦截后的处理类,代理的方法会在它的 invoke() 方法中实现,它又是将拦截的方法转发到不同的 SynchronousMethodHandler 中进行处理
Client 方法调用
从上面获取 Client 实例的过程可以知道,在调 client 的方法时,实例调用的是 Proxy 类的方法,会对应的 SynchronousMethodHandler 拦截执行实际的逻辑。SynchronousMethodHandler 执行的逻辑如下:
Client 默认是 Client.Default 使用的是 HttpURLConnection 发起 http 调用
推荐在实际过程中换成 OkHttpClient 或者 ApacheHttpClient ,它们可以使用到连接池
*如有疑问,欢迎留言交流*
版权声明: 本文为 InfoQ 作者【Yangjing】的原创文章。
原文链接:【http://xie.infoq.cn/article/4f3480da9747a3ed5f7c2264f】。文章转载请联系作者。
评论