zoukankan      html  css  js  c++  java
  • 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的配置就给它覆盖了。

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

  • 相关阅读:
    利用socket.io实现多人聊天室(基于Nodejs)
    【翻译】Ext JS 5的平板支持
    Spring IoC、DI入门小程序
    初学hibernate之缓存
    获取谷歌浏览器缓存视频方法
    JavaScript模块化学习基础
    HTTP Content-type
    初学Hibernate持久化
    初学Hibernate主键生成策略
    初学Hibernate之Query扩展
  • 原文地址:https://www.cnblogs.com/keeya/p/15224772.html
Copyright © 2011-2022 走看看