前提:本案例是基于spring boot 2.7.5,spring cloud 3.1.6,其他版本可能会有些差别!
关于“Did you forget to include spring-cloud-starter-loadbalancer?”报错的原因,网上有一大堆博客供大家参考,这里我给大家提供一种新的参考。
先说结论:
报“Did you forget to include spring-cloud-starter-loadbalancer”的原因之一是可能没有引入"spring-cloud-loadbalancer" pom依赖。
spring boot 启动时执行org.springframework.cloud.openfeign.FeignClientFactoryBean.loadBalance()时,getOptional()范围为null,然后抛出异常“Caused by: java.lang.IllegalStateException: No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalancer?”;
protected <T> T loadBalance(Feign.Builder builder, FeignContext context, HardCodedTarget<T> target) {
//返回为null
Client client = getOptional(context, Client.class);
if (client != null) {
builder.client(client);
applyBuildCustomizers(context, builder);
Targeter targeter = get(context, Targeter.class);
return targeter.target(this, builder, context, target);
}
//到这里抛出异常
throw new IllegalStateException(
"No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalancer?");
}
也就是说,DefaultListableBeanFactory里面没有类型为“feign.Client”的bean;下面的图是当前项目里所有“feign.Client”的实现类:
图一
好的,我就拿Default类做为入口分析一波:
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(LoadBalancerClientsProperties.class)
class DefaultFeignLoadBalancerConfiguration {
@Bean
@ConditionalOnMissingBean
@Conditional(OnRetryNotEnabledCondition.class)
public Client feignClient(LoadBalancerClient loadBalancerClient,
LoadBalancerClientFactory loadBalancerClientFactory) {
return new FeignBlockingLoadBalancerClient(new Client.Default(null, null), loadBalancerClient,
loadBalancerClientFactory);
}
}
也就是说,在DefaultFeignLoadBalancerConfiguration类中会创建FeignBlockingLoadBalancerClient实例,而这个FeignBlockingLoadBalancerClient
public class FeignBlockingLoadBalancerClient implements Client {
private static final Log LOG = LogFactory.getLog(FeignBlockingLoadBalancerClient.class);
private final Client delegate;
private final LoadBalancerClient loadBalancerClient;
private final LoadBalancerClientFactory loadBalancerClientFactory;
}
同样也是FeignClient的实现类。然后我们接着往下看,发现
@ConditionalOnClass(Feign.class)
@ConditionalOnBean({ LoadBalancerClient.class, LoadBalancerClientFactory.class })
@AutoConfigureBefore(FeignAutoConfiguration.class)
@AutoConfigureAfter({ BlockingLoadBalancerClientAutoConfiguration.class, LoadBalancerAutoConfiguration.class })
@EnableConfigurationProperties(FeignHttpClientProperties.class)
@Configuration(proxyBeanMethods = false)
// Order is important here, last should be the default, first should be optional
// see
// https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653
@Import({ HttpClientFeignLoadBalancerConfiguration.class, OkHttpFeignLoadBalancerConfiguration.class,
HttpClient5FeignLoadBalancerConfiguration.class, DefaultFeignLoadBalancerConfiguration.class })
public class FeignLoadBalancerAutoConfiguration {
}
FeignLoadBalancerAutoConfiguration自动配置类,引入了DefaultFeignLoadBalancerConfiguration自动配置类,正常情况下,项目启动时,FeignBlockingLoadBalancerClient会被创建,但是由于FeignBlockingLoadBalancerClient的构造方法会依赖LoadBalancerClientFactory,而LoadBalancerClientFactory存在“spring-cloud-loadbalancer”jar包中,如果没有引入这个jar,项目启动时,会创建FeignBlockingLoadBalancerClient失败,最终会导致DefaultListableBeanFactory里面没有类型为“feign.Client”的bean实例,所以我们启动项目时会报错“No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalancer?”!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。