【SpringCloud】feign.codec.EncodeException: No qualifying bean of type
错误描述
在 Spring Cloud 项目中通过 Open Feign 远程调用时出现如下错误:
feign.codec.EncodeException: No qualifying bean of type 'org.springframework.boot.autoconfigure.http.HttpMessageConverters' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
...
Spring Cloud 版本:Hoxton.SR9
Spring Cloud Alibaba 版本:2.2.2.RELEASE
Spring Boot 版本:2.3.7.RELEASE
错误原因
从报错信息中不难看出,错误原因是容器中缺少 HttpMessageConverters
这样一个 bean 对象。
GitHub 上 spring-cloud/spring-cloud-openfeign 与此相关的 issue:https://github.com/spring-cloud/spring-cloud-openfeign/issues/235。
在 spring-boot-autoconfigure 的较新版本中(具体哪个版本我也不知道),HttpMessageConverters
的自动配置条件更改了,可以参见 HttpMessageConvertersAutoConfiguration
类:
// 这里省去了其他无关注解
@ConditionalOnClass({HttpMessageConverter.class})
@Conditional({HttpMessageConvertersAutoConfiguration.NotReactiveWebApplicationCondition.class})
public class HttpMessageConvertersAutoConfiguration {}
因为现在的 Spring Cloud Gateway 是基于 WebFlux 的,是 Reactive Web。所以根据 @Conditional
的条件,HttpMessageConvertersAutoConfiguration
就不会生效,进而也不会进行自动配置,就导致容器中缺少 HttpMessageConverters
对象。
解决方案
这个问题解决方法也很简单,只需自己写一个配置类,向容器中注册一个 HttpMessageConverters
对象即可。方法可以从 HttpMessageConvertersAutoConfiguration
中复制。参考如下:
@Configuration
public class FeignConfig {
@Bean
@ConditionalOnMissingBean
public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {
return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));
}
}
重启项目,问题解决。
少一些功利主义的追求,多一些不为什么的坚持