FeignClient注解属性configuration不生效问题排查思路

FeignClient注解属性configuration不生效问题排查思路

问题背景

我们知道,"如果需要自定义单个Feign配置,Feign的@Configuration 注解的类不能与@ComponentScan 的包重叠,这样会如果包重叠,将会导致所有的Feign Client都会使用该配置",所以正常使用时,我们在注解上指定单独自定义的配置,不使其全局生效。具体使用教程见我的这篇分享

但有的小伙伴出现了,指定了configuration 却仍旧不生效的问题,博主本人最近也碰见这个问题,排查成功解决了,分享一下排查思路。

排查思路

  1. 首先你需要检查你写的configuration的包路径是可以被spring扫描到的
  2. 如果可以扫描到,请检查你的@FeignClient中的name属性是否与其他client重复,如果重复,有几率导致不生效,为什么是有几率的,参考后续的源码挖掘
  3. 排查你使用的 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一下,你可以看到所有的配置:

image

可以知道存放configuration们的容器其实是一个Map,它们的key是name属性,这也就解释了,为什么有些configuration不生效的原因了。

如果你配置的configuration提前先put进map了,后续的同名configuration的配置就给它覆盖了。

如果到这你都还没有解决问题,那么尝试从源码的堆栈中寻找答案吧。

posted @ 2021-09-03 20:08  上帝爱吃苹果-Soochow  阅读(9201)  评论(0编辑  收藏  举报