本文已参与「新人创作礼」活动,一起开启掘金创作之路。
Feign动态代理接收和处理请求的
@EnableFeignClients 扫描 @FeignClient注解标注的接口。
注册@EnableFeignClients定义的默认配置的BeanDefinition,注册@FeignClient定义的以服务名为隔离方式的配置的BeanDefinition,注册@FeignClient标注的所有接口的FactoryBean的BeanDefinition。
Spring Ioc回调FactroyBean & FeignClientFactoryBean的getObject()方法,注入FeignClient实例到容器。
FeignClientFactoryBean 根据FeignContext获取服务名(contextId)对应的配置信息及组件实例。
构造Feign.Builder,Client & LoadBalancerFeignClient, Targeter & HandCodedTargeter。
构造Feign & ReflectiveFeign,ParseHandlersByName,SynchronousMethodHandler。
构造Proxy,InvocationHandler & FeignInvocationHandler。
JDK动态代理,就是创建一个Proxy。一个匿名类的对象,这个类动态生成,没有名字,实现ProductFacadeServiceFeign接口,访问OrderService,都是在调用Proxy,对Proxy的调用都会交给InvocationHandler & FeignInvocationHandler#invoke()方法。
如果对动态代理发起请求,都会交给FeignInvocationHandler的invoke()方法来处理,在invoke()方法里就可以接收到发起的所有的请求。
args:传递进来的参数
dispatch:methodToHandler包含的就是每个方法名称与MethodHandler的映射。找到方法对应的MethodHandler,将args参数交给他来处理请求
RequestTemplate template = buildTemplateFromArgs.create(argv);
argv:""
RequestTemplate:
GET /product/facade HTTP/1.1 Binary data
用SpringMvcContract解析Spring Mvc的注解,最终拿到的是:
GET /product/facade HTTP/1.1
RequestTemplate:封装了执行请求需要的相关信息,比如请求方式、路径等。
// 查询模板
private final Map<String, QueryTemplate> queries = new LinkedHashMap();
// 消息头模板
private final Map<String, HeaderTemplate> headers;
// 请求的目标地址
private String target;
// URL 后面的片段
private String fragment;
// 是否已解析
private boolean resolved;
// URI 模板
private UriTemplate uriTemplate;
// 请求体模板
private BodyTemplate bodyTemplate;
// 请求方式
private HttpMethod method;
// 字符集
private transient Charset charset;
// 请求体
private Body body;
// 是否斜杠转义
private boolean decodeSlash;
// 集合格式化
private CollectionFormat collectionFormat;
// 方法元数据
private MethodMetadata methodMetadata;
// 代理的目标对象
private Target<?> feignTarget;
RequestTemplate#resolve():核心方法,用于解析数据,创建模板。
Feign 四大模板对象UriTemplate、QueryTemplate、HeaderTemplate、BodyTemplate。
封装在RequestTemplate中,分别对应请求路径、查询参数、消息头、请求体模板。
UriTemplate:
QueryTemplate:
HeaderTemplate:
BodyTemplate:
RequestTemplate.Factory:创建RequestTemplate的工厂,包含MethodMetadata和Encoder对象
其中MethodMetadata是应用初始化时Contract解析@RequestMapping @RequestParam等注解而来的中间数据
Encoder:报文压缩gzip等
RequestInterceptor:为请求附加一些信息,类似spring mvc的interceptor拦截器
Target:主要是把@FeignClient里的url拼接到RequestTemplate
Options:用于请求的参数配置
Decoder:解析返回报文,如果返回404,判断decode404==true则解析,否则交给ErrorDecoder解析
ErrorDecoder:请求错误处理
Logger.Level:日志等级,包含四种 none basic headers full
Logger:对应的配置为LoggerFactory,记录日志用
Retryer:重试,DefaultRetryer默认会重试5次
Client:真正执行http请求的客户端,可以配置,默认由FeignRibbonClientAutoConfiguration进行配置结合ribbon使用