(学习别人的思想,可以找 bug,优化你的代码,提高代码的健壮性)看源码之前要先大致猜想一下 他是怎么实现的?(先使用在分析)
5.1 OpenFeign 的原理是什么?
根据前文的案例,我们知道 feign 是接口调用,接口如果想做事,必须要有实现类可是我们并没有写实现类,只是加了一个@FeignClient(value=”xxx-service”)的注解
所以我们猜测 feign 帮我们创建了代理对象,然后完成真实的调用。
动态代理 1.jdk (invoke) 2.cglib 子类继承的
-
给接口创建代理对象(启动扫描)
-
代理对象执行进入 invoke 方法
-
在 invoke 方法里面做远程调用
具体我们这次的流程:
A. 扫描注解得到要调用的服务名称和 url
B. comsumer拿到 provider-order-service/doOrder,通过 ribbon 的负载均衡拿到一个服务,provider-order-service/doOrder—》http://ip:port/doOrder
C. comsumer发起请求,远程调用。
5.2 看看 OpenFeign 的内部是如何实现这些的
5.2.1 如何扫描注解@FeignClient
查看启动类的注解@EnableFeignClients
进入 FeignClientsRegistrar 这个类 去查看里面的东西
真正的扫描拿到注解和服务名称
5.2.2 如何创建代理对象去执行调用?
当我们启动时,在 ReflectiveFeign 类的 newInstance 方法,给接口创建了代理对象
当我们执行调用的时候,打个断点去查看
ReflectiveFeign 类中的 invoke 方法帮我们完成调用
SynchronousMethodHandler 的 invoke 中给每一个请求创建了一个 requestTemplate 对象,去执行请求
executeAndDecode
我们去看 LoadBalancerFeignClient 的 execute 方法
executeWithLoadBalancer 继续往下看
只要是 feign 调用出了问题
看 feign 包下面的 Client 接口下面的 108 行
200 成功
400 请求参数错误
401 没有权限
403 权限不够
404 路径不匹配
405 方法不允许
500 提供者报错了
302 资源重定向
完整流程
OpenFeign 总结
OpenFeign 主要基于接口和注解实现了远程调用
源码总结:面试
- OpenFeign 用过吗?它是如何运作的?
在主启动类上加上**@EnableFeignClients 注解后,启动会进行包扫描,把所有加了@FeignClient(value=”xxx-service”)注解的接口进行创建代理对象 通过代理对象,底层使用ribbon 做了负载均衡和远程调用**
- 如何创建的代理对象?
当 项 目 在 启 动 时 , 先 扫 描 , 然 后 拿 到 标 记 了 @FeignClient 注 解 的 接 口 信 息 , 由ReflectiveFeign 类的 newInstance 方法创建了代理对象 JDK 动态代理
- OpenFeign 到底是用什么做的远程调用?
使用的是 HttpURLConnection (java.net)
- OpenFeign 怎么和 ribbon 整合的?
在代理对象执行调用的时候
OpenFeign 的日志功能
NONE 默认的,不显示日志
BASE 仅记录请求方法,URL ,响应状态码及执行时间
HEADERS 在 BASE 之上增加了请求和响应头的信息
FULL 在 HEADERS 之上增加了请求和响应的正文及无数据
创建配置类
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLogger() {
return Logger.Level.FULL;}
yml
logging:
level:
com.bjpowernode.feign.UserOrderFeign: debug