暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

玩转OpenFeign-续集

Java艺术 2021-09-07
534
关注 “Java艺术” 我们一起成长!



上一篇《玩转OpenFeign
》介绍了OpenFeign
的一些常用配置,不过还漏了点内容。


Client连接超时、读超时的配置



这篇主要介绍如何为不同的Client
配置不同的连接超时、读超时这类参数,并从源码角度分析配置是怎么起作用的,以及都可以配置哪些参数,内容不多


还是要从FeignAutoConfiguration
这个自动配置类说起,该配置类使用@EnableConfigurationProperties
注册了两个用于装载OpenFeign
配置的Bean
,分别是FeignClientProperties
FeignHttpClientProperties

  • FeignHttpClientProperties
    :用于配置HttpClient
    HttpClient是真正用于发起Http请求的客户端工具类。


如果OpenFeign
Client
使用的是默认的Default
,由于Default
这个Client
使用的HttpClient
HttpURLConnection
,所以FeignHttpClientProperties
这个配置不会使用到。建议不使用默认的Default


如果OpenFeign
Client
使用的是OkHttpClient
,那么FeignHttpClientProperties
则用于装载OkHttpClient
的连接池、全局连接超时配置。


  • FeignClientProperties
    :为每个Client
    配置连接超时、读超时、重试器、请求拦截器等。支持哪些配置参数可查看FeignClientProperties
    的内部类FeignClientConfiguration
    有哪些字段。


FeignClientProperties
用于接收在application.yaml
配置文件中为每个Client
配置的连接超时、读超时、重试器、请求拦截器、编码器、解码器这类参数。


配置重试器、请求拦截器等不建议在application.yaml
中配置,因为在application.yaml
中配置重试器、请求拦截器的类名,OpenFeign
是从Spring Boot
启动应用的ApplicationContext
中根据类名获取Bean
的,并没有使用OpenFeign
提供的Client
隔离的ApplicationContext


除非你想全部Client
都使用相同的重试器和请求拦截器,否则不建议这样配置。既然都需要在代码中创建这些重试器、请求拦截器这些Bean
,那么直接在代码中配置不是更方法吗。在上一篇已经介绍如何通过代码方式实现为不同Client
配置不同的重试器、请求拦截器。


通过代码方式配置连接超时、读超时这些参数可通过给在Client
ApplicationContext
注入一个Request.Options
类型的Bean
实现。


首先创建自动配置类Configuration
,往容器中注入Request.Options,给Request.Options配置连接超时和读超时,如下图所示。



不要在这个配置类上并@Configuration注解,因为这不是注册到应用的ApplicationContext,而是注册到OpenFeignClient创建的ApplicationContext


最后给@FeignClient
注解的configuration
属性添加这个配置类。


再来看下如何在application.yaml
中配置Client连接超时、读超时这些参数


接收feign.client.config
配置的类为FeignClientConfiguration


config字段是个map
,支持多个配置,每个Client
配置的key
Client
的名称(服务提供者名称),value
类型为FeignClientConfiguration
。支持配置连接超时(connectTimeout
)、读超时(readTimeout
)等参数。


从源码分析配置是怎么生效的



OpenFeign
会将使用@FeignClient
注解注释的接口扫描出来,并往每个Client
各自的ApplicationContext
注入一个FeignClientFactoryBean
,该FeignClientFactoryBean
getObject
方法返回的是接口的代码对象。


FeignClientFactoryBean
在创建接口的代理对象时,会先生成一个Feign.Builder
,然后使用这个Feign.Builder
创建代理对象。


FeignClientFactoryBean
在创建Feign.Builder
后会读取配置,将配置写入到Feign.Builder
Feign.Builder
在创建代理对象时就会使用上这些配置,最后用于创建方法拦截器SynchronousMethodHandler


FeignClientFactoryBeanFeign.Builder
填充配置的源码如下。



从上面源码可以看出,我们在application.yaml
中配置default-to-properties
true
实际目的是不要让默认配置覆盖我们在application.yaml
中添加的配置。


如果项目中使用Ribbon
,那么FeignRibbonClientAutoConfiguration
会注入一个Request.Options
,当default-to-properties
配置为false
时,这个Request.Options
就会覆盖application.yaml
中添加的配置。所以要将default-to-properties
配置为true
,配置才生效。


从上面源码还发现一个参数inheritParentContext
,这个inheritParentContext
的值默认为true
。当配置inheritParentContext
false
时,我们在application.yaml
中添加的配置就都不会生效。


如果想要将inheritParentContext
设置为false
,该如何设置呢?


@FeignClient
注解的configuration
属性指定的配置类中注入一个FeignClientConfigurer
类型的Bean
,实现FeignClientConfigurer
接口的inheritParentConfiguration
方法,在方法中返回false
即可。


实际我们关心的还是创建出来的代理对象的方法拦截器(SynchronousMethodHandler
)。在创建SynchronousMethodHandler
Feign.Builder
会将封装了连接超时、读超时配置的Request.Options
对象传递给SynchronousMethodHandler
。在发起请求时,由SynchronousMethodHandler
Request.Options
配置对象传给Client
,如OkHttpClient


每种Client
实现的方式不同,OkHttpClient
的实现是,当全局配置的连接超时与当前Client
配置的连接超时不同时,重新创建HttpClient,即重新创建用于真正发起Http请求的OkHttpClient
,使用的还是相同的连接池。


往期原创精选
玩转OpenFeign
OpenFeign与Ribbon源码分析总结(面试题)
Spring Cloud Ribbon源码分析(Spring Cloud Kubernetes)
Spring Cloud OpenFeign源码分析




[Java艺术] 微信号:javaskill
一个只推送原创文章的技术公众号,分享Java后端相关技术。


文章转载自Java艺术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论