曹耘豪的博客

Spring Cloud之Feign

  1. 依赖
  2. 自定义Http Client
    1. Apache Http Client
    2. OkHttp
  3. Client的扫描
  4. Feign接口仅支持继承一个接口
  5. 自定义feign超时

依赖

build.gradle
1
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'

自定义Http Client

Apache Http Client

1
implementation 'io.github.openfeign:feign-httpclient'

OkHttp

1
implementation 'io.github.openfeign:feign-okhttp'

Client的扫描

1
2
3
4
5
6
7
8
9
@EnableFeignClients(basePackageClasses = {
Application.class, // 本项目根路径
OtherClient.class // 其他包的Client
})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

注意:使用@ComponentScan无效

Feign接口仅支持继承一个接口

Contract.parseAndValidateMetadata

自定义feign超时

全局默认

1
2
feign.client.config.default.connect-timeout=10000
feign.client.config.default.read-timeout=60000

指定FeignClient的配置

1
2
feign.client.config.myContextId.connect-timeout=10000
feign.client.config.myContextId.read-timeout=60000

Spring构造Feign Client流程

org.springframework.cloud.openfeign.FeignClientFactoryBean#configureFeign

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protected void configureFeign(FeignContext context, Feign.Builder builder) {
FeignClientProperties properties = beanFactory != null ? beanFactory.getBean(FeignClientProperties.class)
: applicationContext.getBean(FeignClientProperties.class);

FeignClientConfigurer feignClientConfigurer = getOptional(context, FeignClientConfigurer.class);
setInheritParentContext(feignClientConfigurer.inheritParentConfiguration());

if (properties != null && inheritParentContext) {
if (properties.isDefaultToProperties()) {
configureUsingConfiguration(context, builder);
configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()), builder);
configureUsingProperties(properties.getConfig().get(contextId), builder);
}
else {
configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()), builder);
configureUsingProperties(properties.getConfig().get(contextId), builder);
configureUsingConfiguration(context, builder);
}
}
else {
configureUsingConfiguration(context, builder);
}
}
   / 
  ,