不说什么开场白了,直接看详细的错误堆栈信息:
2021-03-09 13:19:01.333 WARN 10452 --- [ restartedMain] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration': Unsatisfied dependency expressed through field 'optionalArgs'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.netflix.discovery.AbstractDiscoveryClientOptionalArgs<?>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
2021-03-09 13:19:01.355 INFO 10452 --- [ restartedMain] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-03-09 13:19:01.407 ERROR 10452 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field optionalArgs in org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration required a bean of type 'com.netflix.discovery.AbstractDiscoveryClientOptionalArgs' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.netflix.discovery.AbstractDiscoveryClientOptionalArgs' in your configuration.
Process finished with exit code 0上面错误的大概意思为:在内部类 org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration
中 optionalArgs 字段依赖注入失败:
@Autowired private AbstractDiscoveryClientOptionalArgs<?> optionalArgs;
为什么会注入失败呢?进入到 AbstractDiscoveryClientOptionalArgs 抽象类,他提供了如下子类实现:

点击进入 RestTemplateDiscoveryClientOptionalArgs 子类,看看那些地方在使用它。在 DiscoveryClientOptionalArgsConfiguration 类中的 restTemplateDiscoveryClientOptionalArgs() 方法,它用来创建 RestTemplateDiscoveryClientOptionalArgs 对象,代码如下:
@Bean
@ConditionalOnClass(name = "org.springframework.web.client.RestTemplate")
@ConditionalOnMissingClass("com.sun.jersey.api.client.filter.ClientFilter")
@ConditionalOnMissingBean(value = { AbstractDiscoveryClientOptionalArgs.class }, search = SearchStrategy.CURRENT)
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", matchIfMissing = true,
havingValue = "false")
public RestTemplateDiscoveryClientOptionalArgs restTemplateDiscoveryClientOptionalArgs(TlsProperties tlsProperties,
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier)
throws GeneralSecurityException, IOException {
logger.info("Eureka HTTP Client uses RestTemplate.");
RestTemplateDiscoveryClientOptionalArgs result = new RestTemplateDiscoveryClientOptionalArgs(
eurekaClientHttpRequestFactorySupplier);
setupTLS(result, tlsProperties);
return result;
}创建 RestTemplateDiscoveryClientOptionalArgs 对象是有条件,其中一个条件是类路径中必须有类才能创建它(因为有 @ConditionalOnClass 注解修饰)。而 RestTemplate 位于 spring-web-5.3.4.jar 文件。而 spring-web 位于中,如下图:

因此,我们需要引入 spring-boot-start-web 依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
问题解决了!
有读者会问,你怎么知道需要创建 RestTemplateDiscoveryClientOptionalArgs 类的对象,而不是其他子类呢?
(1)看看 DiscoveryClientOptionalArgs 类,根本没有被 new,如下图:

(2)看看 Jersey1DiscoveryClientOptionalArgs 类,没有地方在使用,如下图:

(3)看看 MutableDiscoveryClientOptionalArgs 类,创建代码如下:
@Bean
@ConditionalOnClass(name = "com.sun.jersey.api.client.filter.ClientFilter")
@ConditionalOnMissingBean(value = AbstractDiscoveryClientOptionalArgs.class, search = SearchStrategy.CURRENT)
public MutableDiscoveryClientOptionalArgs discoveryClientOptionalArgs(TlsProperties tlsProperties)
throws GeneralSecurityException, IOException {
logger.info("Eureka HTTP Client uses Jersey");
MutableDiscoveryClientOptionalArgs result = new MutableDiscoveryClientOptionalArgs();
setupTLS(result, tlsProperties);
return result;
}他需要依赖 com.sun.jersey.api.client.filter.ClientFilter,过过……
(4)看看 WebClientDiscoveryClientOptionalArgs 类,下面是创建 WebClientDiscoveryClientOptionalArgs 的代码:
@ConditionalOnMissingClass("com.sun.jersey.api.client.filter.ClientFilter")
@ConditionalOnClass(name = "org.springframework.web.reactive.function.client.WebClient")
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", havingValue = "true")
protected static class WebClientConfiguration {
@Autowired
private TlsProperties tlsProperties;
@Bean
@ConditionalOnMissingBean(
value = { AbstractDiscoveryClientOptionalArgs.class, RestTemplateDiscoveryClientOptionalArgs.class },
search = SearchStrategy.CURRENT)
public WebClientDiscoveryClientOptionalArgs webClientDiscoveryClientOptionalArgs(
ObjectProvider<WebClient.Builder> builder) throws GeneralSecurityException, IOException {
logger.info("Eureka HTTP Client uses WebClient.");
WebClientDiscoveryClientOptionalArgs result = new WebClientDiscoveryClientOptionalArgs(
builder::getIfAvailable);
setupTLS(result, tlsProperties);
return result;
}
}在 @ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", havingValue = "true") 中定义了,它需要依赖 webclient.enabled 属性。并且在 webClientDiscoveryClientOptionalArgs() 方法上还有 @ConditionalOnMissingBean 进行限制。
是不是感觉解决问题的思路清晰了那么一点点呢!!!
下图是问题解决后打断点查看 optionalArgs 字段的真实类型:

谢谢支持……希望能帮助到你!
看到你写的这篇文章,非常详细,感谢你
谢谢支持!