介绍
背景
在编写简单的Spring Cloud示例中,使用自动注入的BalancerClient访问注册中心的实例(instance)。
项目参考:https://blog.csdn.net/BS0003/article/details/110000862中的eureka-registry-consumer-original子模块
好奇之下,想要了解LoadBalancerClient的默认实现。
过程
查看源码,有两个实现了LoadBalancerClient的类
- org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient
- org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient
在eureka-registry-consumer-original中,将Ribbon的依赖jar从项目去除。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</exclusion>
</exclusions>
</dependency>
启动项目报错。
错误提示
***************************
APPLICATION FAILED TO START
***************************
Description:
Field loadBalancerClient in com.chyong.ribbon.ContentFromCenterController required a bean of type 'org.springframework.cloud.client.loadbalancer.LoadBalancerClient' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
The following candidates were found but could not be injected:
- Bean method 'blockingLoadBalancerClient' in 'BlockingLoadBalancerClientAutoConfiguration.BlockingLoadbalancerClientConfig' not loaded because AnyNestedCondition 0 matched 2 did not; NestedCondition on OnNoRibbonDefaultCondition.RibbonLoadBalancerNotPresent @ConditionalOnMissingClass found unwanted class 'org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient'; NestedCondition on OnNoRibbonDefaultCondition.RibbonNotEnabled @ConditionalOnProperty (spring.cloud.loadbalancer.ribbon.enabled=false) did not find property 'spring.cloud.loadbalancer.ribbon.enabled'
- Bean method 'loadBalancerClient' in 'RibbonAutoConfiguration' not loaded because AllNestedConditions 3 matched 1 did not; NestedCondition on RibbonAutoConfiguration.RibbonClassesConditions.RibbonPresent @ConditionalOnClass did not find required class 'com.netflix.ribbon.Ribbon'; NestedCondition on RibbonAutoConfiguration.RibbonClassesConditions.AsyncRestTemplatePresent @ConditionalOnClass found required class 'org.springframework.web.client.AsyncRestTemplate'; NestedCondition on RibbonAutoConfiguration.RibbonClassesConditions.RestTemplatePresent @ConditionalOnClass found required class 'org.springframework.web.client.RestTemplate'; NestedCondition on RibbonAutoConfiguration.RibbonClassesConditions.IClientPresent @ConditionalOnClass found required class 'com.netflix.client.IClient'
根据错误提示(读起来费劲),跟踪源码(手动,电脑不行)
大体的意思:
LoadBalancerClient注入失败。原因BlockingLoadbalancerClientConfig.blockingLoadBalancerClient没有加载,原因是@Conditional(OnNoRibbonDefaultCondition.class)失败
@Conditional(OnNoRibbonDefaultCondition.class)
protected static class BlockingLoadbalancerClientConfig {...}
接着看OnNoRibbonDefaultCondition类源码,错误提示是
NestedCondition on OnNoRibbonDefaultCondition.RibbonNotEnabled @ConditionalOnProperty (spring.cloud.loadbalancer.ribbon.enabled=false) did not find property 'spring.cloud.loadbalancer.ribbon.enabled'
发现这里说找不到’spring.cloud.loadbalancer.ribbon.enabled’属性
在eureka-registry-consumer-original项目的yml中添加
spring:
cloud:
loadbalancer:
ribbon:
enabled: false
重新启动,成功。
总结
- LoadBalancerClient的默认实现是RibbonLoadBalancerClient
- 如果项目中没有RibbonLoadBalancerClient,那么需要在yml中添加以上的配置,从而可以让BlockingLoadBalancerClient生效。
对源码的了解还是一知半解。还写下以后需要再补充。
版权声明:本文为BS0003原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。