FeignClient註解屬性configuration不生效問題排查思路

Soochow發表於2021-09-03

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的配置就給它覆蓋了。

如果到這你都還沒有解決問題,那麼嘗試從原始碼的堆疊中尋找答案吧。

相關文章