FeignClient注解属性configuration不生效问题排查思路 – 上帝爱吃苹果
FeignClient注解属性configuration不生效问题排查思路
问题背景
我们知道,”如果需要自定义单个Feign配置,Feign的@Configuration 注解的类不能与@ComponentScan 的包重叠,这样会如果包重叠,将会导致所有的Feign Client都会使用该配置”,所以正常使用时,我们在注解上指定单独自定义的配置,不使其全局生效。具体使用教程见我的这篇分享。
但有的小伙伴出现了,指定了configuration 却仍旧不生效的问题,博主本人最近也碰见这个问题,排查成功解决了,分享一下排查思路。
排查思路
- 首先你需要检查你写的configuration的包路径是可以被spring扫描到的
- 如果可以扫描到,请检查你的@FeignClient中的name属性是否与其他client重复,如果重复,有几率导致不生效,为什么是有几率的,参考后续的源码挖掘
- 排查你使用的 name 是否与引用jar包中的client重复了,或者干脆随便打几个字母,重新启动尝试一下
源码挖掘
被@FeignClient注解的接口会在项目启动时,被spring容器扫描到,开始一系列的准备工作,最重要的是 FeignClientFactoryBean#configureUsingConfiguration()步骤,这个是开始加载你自定义的configuration中的Retryer、RequestInterceptor等等…
FeignClientFactoryBean.java
protected void configureUsingConfiguration(FeignContext context,
Feign.Builder builder) {
Logger.Level level = getOptional(context, Logger.Level.class);
if (level != null) {
builder.logLevel(level);
}
Retryer retryer = getOptional(context, Retryer.class);
if (retryer != null) {
builder.retryer(retryer);
}
ErrorDecoder errorDecoder = getOptional(context, ErrorDecoder.class);
if (errorDecoder != null) {
builder.errorDecoder(errorDecoder);
}
Request.Options options = getOptional(context, Request.Options.class);
if (options != null) {
builder.options(options);
}
Map<String, RequestInterceptor> requestInterceptors = context
.getInstances(this.contextId, RequestInterceptor.class);
if (requestInterceptors != null) {
builder.requestInterceptors(requestInterceptors.values());
}
if (this.decode404) {
builder.decode404();
}
}
从FeignContext类的对象context你可以拿到整个项目所有的FeignClient的上下文参数,debug一下,你可以看到所有的配置:
可以知道存放configuration们的容器其实是一个Map,它们的key是name属性,这也就解释了,为什么有些configuration不生效的原因了。
如果你配置的configuration提前先put进map了,后续的同名configuration的配置就给它覆盖了。
如果到这你都还没有解决问题,那么尝试从源码的堆栈中寻找答案吧。