Netflix Feign - Spring Cloud 整合 Feign 源码(七)

185 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。


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使用