在我们利用spring-cloud-openfeign的时候,不同的client可能需要一些自定义的配置,我们可以在配置文件中配置,也可以写相应的配置类。而写配置类有一个易掉的坑,接下来就来讲解一下这个坑以及解决方案!
先来看一段常见的代码。
一 代码
@FeignClient(name = "${feign.name}", url = "${feign.url}", configuration=FooConfiguration.class)
public interface FooClient {
@GetMapping("/users/{id}")
User findById(@PathVariable("id") Long id);
/**
* 注意:
* 1. 该类可以独立出去;
* 2. 该类上也可添加@Configuration声明是一个配置类;
* 配置类上也可添加@Configuration注解,声明这是一个配置类;
* 但此时千万别将该放置在主应用程序上下文@ComponentScan所扫描的包中,
* 否则,该配置将会被所有Feign Client共享,无法实现细粒度配置!
*/
@Configuration
public class FooConfiguration {
@Bean
public Contract feignContract() {
return new feign.Contract.Default();
}
@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor("user", "password");
}
}
}
上面的配置是我从官网直接copy下来的。这样写,产生的效果是什么?如果配置类在@ComponentScan
扫描路径,则该配置默认会全局生效。所以如果不仔细看一下官方文档,很容易进坑,官方文档也给出了注意点:
FooConfiguration does not need to be annotated with @Configuration. However, if it is, then take care to exclude it from any @ComponentScan that would otherwise include this configuration as it will become the default source for feign.Decoder, feign.Encoder, feign.Contract, etc., when specified. This can be avoided by putting it in a separate, non-overlapping package from any @ComponentScan or @SpringBootApplication, or it can be explicitly excluded in @ComponentScan.
为达到目的,可以直接去掉FooConfiguration
类上的@Configuration
注解。
二 总结
- 配置类上也可添加
@Configuraiton
注解,声明这是一个配置类;但此时千万别将该放置在主应用程序上下文@ComponentScan
所扫描的包中,否则,该配置将会被所有Feign Client共享(相当于变成了通用配置,其实本质还是Spring父子上下文扫描包重叠导致的问题),无法实现细粒度配置! - 可以直接采用配置文件的配置方式(Edgware开始提供)