前言
最近公司新老项目对接过程中使用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配置内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论