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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM