java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringCloud FeignClient配置

SpringCloud中FeignClient自定义配置

作者:一乐小哥

使用FeignClient时需了解其默认配置机制,通过注入Decoder、Encoder等Bean实现自定义配置,下面就来介绍一下如何使用,感兴趣的可以了解一下

前言

最近公司新老项目对接过程中使用feginClient进行调用时遇到了很多问题,在此做些简短的总结记录

一、Feign的配置原理

当我们配置一个feignClient的时候,通常的写法是这样的

@FeignClient("xxxClient")
public interface xxxClient{
}

当我们做这个实际上就是生成一个默认的FeignClient, 其配置在org.springframework.cloud.openfeign 包下的FeignClientsConfiguration

@Configuration
public class FeignClientsConfiguration {
	@Autowired
	private ObjectFactory<HttpMessageConverters> messageConverters;
	@Autowired(required = false)
	private List<AnnotatedParameterProcessor> parameterProcessors = new ArrayList<>();
	@Autowired(required = false)
	private List<FeignFormatterRegistrar> feignFormatterRegistrars = new ArrayList<>();
	@Autowired(required = false)
	private Logger logger;
	@Bean
	@ConditionalOnMissingBean
	public Decoder feignDecoder() {
		return new OptionalDecoder(new ResponseEntityDecoder(new SpringDecoder(this.messageConverters)));
	}
	@Bean
	@ConditionalOnMissingBean
	public Encoder feignEncoder() {
		return new SpringEncoder(this.messageConverters);
	}
	@Bean
	@ConditionalOnMissingBean
	public Contract feignContract(ConversionService feignConversionService) {
		return new SpringMvcContract(this.parameterProcessors, feignConversionService);
	}
	@Bean
	public FormattingConversionService feignConversionService() {
		FormattingConversionService conversionService = new DefaultFormattingConversionService();
		for (FeignFormatterRegistrar feignFormatterRegistrar : feignFormatterRegistrars) {
			feignFormatterRegistrar.registerFormatters(conversionService);
		}
		return conversionService;
	}

	@Configuration
	@ConditionalOnClass({ HystrixCommand.class, HystrixFeign.class })
	protected static class HystrixFeignConfiguration {
		@Bean
		@Scope("prototype")
		@ConditionalOnMissingBean
		@ConditionalOnProperty(name = "feign.hystrix.enabled")
		public Feign.Builder feignHystrixBuilder() {
			return HystrixFeign.builder();
		}
	}
	@Bean
	@ConditionalOnMissingBean
	public Retryer feignRetryer() {
		return Retryer.NEVER_RETRY;
	}
	@Bean
	@Scope("prototype")
	@ConditionalOnMissingBean
	public Feign.Builder feignBuilder(Retryer retryer) {
		return Feign.builder().retryer(retryer);
	}
	@Bean
	@ConditionalOnMissingBean(FeignLoggerFactory.class)
	public FeignLoggerFactory feignLoggerFactory() {
		return new DefaultFeignLoggerFactory(logger);
	}
}

可以看到这上面所有注入的bean都有一个注解@ConditionalOnMissingBean,也就没有自定义则触发创建Bean

这一段Bean的注入在FeignClientFactoryBean中的这段代码, 当服务启动时触发

protected Feign.Builder feign(FeignContext context) {
		FeignLoggerFactory loggerFactory = get(context, FeignLoggerFactory.class);
		Logger logger = loggerFactory.create(type);

		// @formatter:off 从spring上下文中获取对应的Bean
		Feign.Builder builder = get(context, Feign.Builder.class)
				// required values
				.logger(logger)
				.encoder(get(context, Encoder.class))
				.decoder(get(context, Decoder.class))
				.contract(get(context, Contract.class));
		// @formatter:on

		configureFeign(context, builder);

		return builder;
	}

二、自定义配置

这就意味着如果我们需要自定义FeignClient的相关配置可以直接注入其中一个bean就可以了

类似于

@Configuration
public class FeignClientsConfiguration {

    @Bean
    public Decoder feignDecoder() {
        return new ResultDecoder();
    }

    @Bean
    public Encoder feignEncoder() {
        return new ParamEncoder();
    }

    @Bean
    public Contract feignContract() {
        return new DefaultContract();
    }
}

如上所示, 我分别注入了Decoder、Encoder、Contract, 而其他几项依然还是feign默认值.

三、专有配置

那么如果我想为一个client单独加一些配置又应该如何做呢?

点开@FeignClient可以看到里面有一项configuration

/**
	 * A custom <code>@Configuration</code> for the feign client. Can contain override
	 * <code>@Bean</code> definition for the pieces that make up the client, for instance
	 * {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.
	 *
	 * @see FeignClientsConfiguration for the defaults
	 */
	Class<?>[] configuration() default {};

所以我们可以写一个如下的configuration

public class SelfFeignClientsConfiguration {
    @Bean
    @ConditionalOnMissingBean(name = "SelfFeignDecoder")
    public Decoder SelfFeignDecoder() {
        return new JacksonDecoder();
    }
}

再在feignClient上引入

@FeignClient(name = "xxxClient", configuration = SelfFeignClientsConfiguration.class)
public interface xxxClient{
}

如此即可完成对xxxClient更细粒度的配置.

到此这篇关于SpringCloud中FeignClient自定义配置的文章就介绍到这了,更多相关SpringCloud FeignClient配置内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文