关于springboot:Did-you-forget-to-include-springcloudstarterloadbalancer原因探究

前提:本案例是基于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?”!

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理