Spring Boot迁移至2.7.18+Spring Cloud 2021.0.3后Ribbon配置异常求助
问题
将Spring Boot从2.2.6.RELEASE版本迁移至2.7.18版本,搭配Spring Cloud 2021.0.3版本后,启动时出现如下异常:
java.lang.IllegalStateException: Error processing condition on org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration.loadBalancerClient at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:193) at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:153) at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:129) at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:343) at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112) at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:756) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:572) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:409) at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1289) at com.unilog.prime.tmb.TMBApplication.main(TMBApplication.java:24) Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@76ed5528] at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:485) at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:361) at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:418) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.lambda$getTypeForFactoryMethod$2(AbstractAutowireCapableBeanFactory.java:765) at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:764) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:703) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:674) at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1684) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:570) at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:542) at org.springframework.boot.autoconfigure.condition.OnBeanCondition.collectBeanNamesForType(OnBeanCondition.java:246) at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:239) at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:229) at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchingBeans(OnBeanCondition.java:182) at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:157) at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ... 17 common frames omitted Caused by: java.lang.NoClassDefFoundError: org/springframework/cloud/client/loadbalancer/LoadBalancedRetryPolicyFactory at java.base/java.lang.Class.getDeclaredMethods0(Native Method) at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3578) at java.base/java.lang.Class.getDeclaredMethods(Class.java:2676) at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:467) ... 33 common frames omitted Caused by: java.lang.ClassNotFoundException: org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526) ... 37 common frames omitted
已尝试如下依赖配置,但未解决问题:
<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-ribbon</artifactId> </exclusion> <exclusion> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon-eureka</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency>
需要调整哪些依赖或配置来解决该错误?
解决方案
这个问题的核心是Ribbon已被Spring Cloud弃用,在2021.0.x(Jubilee)版本中,官方推荐使用Spring Cloud LoadBalancer替代Ribbon,但项目中仍有Ribbon相关自动配置类尝试加载,导致找不到已移除的LoadBalancedRetryPolicyFactory类。可按以下步骤处理:
彻底排除所有Ribbon相关依赖
除了在eureka-client中排除ribbon starter,还需排查是否有其他依赖间接引入Ribbon。可通过mvn dependency:tree命令查看依赖树,找到所有Ribbon相关依赖并排除。优化后的eureka-client依赖配置:<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <exclusions> <!-- 排除所有Ribbon相关依赖 --> <exclusion> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </exclusion> <exclusion> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon</artifactId> </exclusion> <exclusion> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon-core</artifactId> </exclusion> <exclusion> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon-eureka</artifactId> </exclusion> <exclusion> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon-loadbalancer</artifactId> </exclusion> </exclusions> </dependency>禁用Ribbon自动配置
在启动类上添加注解,彻底阻止Ribbon自动配置类加载:@SpringBootApplication(exclude = {RibbonAutoConfiguration.class}) public class TMBApplication { public static void main(String[] args) { SpringApplication.run(TMBApplication.class, args); } }确保Spring Cloud LoadBalancer配置正确
确认spring-cloud-starter-loadbalancer依赖已正确引入,且版本与Spring Cloud 2021.0.3匹配。若项目使用RestTemplate或WebClient,需用@LoadBalanced注解标记,以启用负载均衡能力:@Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); }清理旧的Ribbon配置
检查项目配置文件(application.yml/application.properties),删除所有以ribbon.开头的配置项,避免遗留配置引发冲突。
内容的提问来源于stack exchange,提问作者Harshal_Kalavadiya

