在前一篇文章《探究Eureka 在 Spring Boot 中的配置注入与统一管理机制》中,我们揭示了springboot项目在启动时,启动类Main或者Application会通过@EnableAutoConfiguration注解开启Eureka的自动配置,今天我们来揭秘具体哪些Eureka的自动配置类会被加载到Spring容器中。
由前一篇文章《探究 Eureka 在 Spring Boot 中的配置注入与统一管理机制》可知,通过selectImports方法获取到的Eureka自动配置类有7个。
1. EurekaClientConfigServerAutoConfiguration
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties
@ConditionalOnClass({ EurekaInstanceConfigBean.class, EurekaClient.class,
ConfigServerProperties.class })
public class EurekaClientConfigServerAutoConfiguration {
……
}
- 生效的条件:EurekaInstanceConfigBean, EurekaClient,ConfigServerProperties类必须存在
- 核心方法:OnClassCondition#getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata)
该方法会从metadata中获取所有带有@ConditionalOnClass注解的类,然后检查当前ClassLoader中是否存在这些类。如果发现有缺失的类,则记录缺失的类名并返回.
- 日志
EurekaClientConfigServerAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.springframework.cloud.config.server.config.ConfigServerProperties' (OnClassCondition)
小结:EurekaClientConfigServerAutoConfiguration不会生效,因为ConfigServerProperties类不存在。
2. DiscoveryClientOptionalArgsConfiguration
@Configuration(proxyBeanMethods = false)
public class DiscoveryClientOptionalArgsConfiguration {
……
}
不受条件注解影响,默认生效。
3. EurekaClientAutoConfiguration
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties
@ConditionalOnClass(EurekaClientConfig.class)
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
@ConditionalOnDiscoveryEnabled
@AutoConfigureBefore({ NoopDiscoveryClientAutoConfiguration.class,
CommonsClientAutoConfiguration.class, ServiceRegistryAutoConfiguration.class })
@AutoConfigureAfter(name = {
"org.springframework.cloud.netflix.eureka.config.DiscoveryClientOptionalArgsConfiguration",
"org.springframework.cloud.autoconfigure.RefreshAutoConfiguration",
"org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration",
"org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration" })
public class EurekaClientAutoConfiguration {
……
}
- 生效的条件:类路径中包含EurekaClientConfig类并且
- 核心方法:OnPropertyCondition#getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata)
实现:该方法调用determineOutcome(annotationAttributes, context.getEnvironment())从上下文中获取相关配置,包括缺失的,属性值不同的等,最后去判断条件是否满足。
类是否存在的判断同EurekaClientConfigServerAutoConfiguration,这里就不在重复赘述了。
- 日志
EurekaClientAutoConfiguration matched:
- @ConditionalOnClass found required class 'com.netflix.discovery.EurekaClientConfig' (OnClassCondition)
- @ConditionalOnProperty (eureka.client.enabled) matched; @ConditionalOnProperty (spring.cloud.discovery.enabled) matched (OnPropertyCondition)
小结:EurekaClientAutoConfiguration生效。
4. RibbonEurekaAutoConfiguration
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties
@ConditionalOnRibbonAndEurekaEnabled
@AutoConfigureAfter(RibbonAutoConfiguration.class)
@RibbonClients(defaultConfiguration = EurekaRibbonClientConfiguration.class)
public class RibbonEurekaAutoConfiguration {
}
- 生效的条件:Ribbon和Eureka都启用时生效
- 实现:依赖@ConditionalOnRibbonAndEurekaEnabled,而该注解有内部类Defaults和OnEurekaClientEnabled以及EurekaBeans。属性eureka.client.enabled和ribbon.eureka.enabled默认为开启状态。
@Conditional(ConditionalOnRibbonAndEurekaEnabled.OnRibbonAndEurekaEnabledCondition.class)
public @interface ConditionalOnRibbonAndEurekaEnabled {
class OnRibbonAndEurekaEnabledCondition extends AllNestedConditions {
……
@ConditionalOnClass(DiscoveryEnabledNIWSServerList.class)
@ConditionalOnBean(SpringClientFactory.class)
@ConditionalOnProperty(value = "ribbon.eureka.enabled", matchIfMissing = true)
static class Defaults {
}
……
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
@ConditionalOnDiscoveryEnabled
static class OnEurekaClientEnabled {
}
}
}
- 日志
RibbonEurekaAutoConfiguration matched:
- AllNestedConditions 3 matched 0 did not; NestedCondition on ConditionalOnRibbonAndEurekaEnabled.OnRibbonAndEurekaEnabledCondition.OnEurekaClientEnabled found matching nested conditions @ConditionalOnProperty (eureka.client.enabled) matched; @ConditionalOnProperty (spring.cloud.discovery.enabled) matched, @ConditionalOnProperty (eureka.client.enabled) matched; @ConditionalOnProperty (spring.cloud.discovery.enabled) matched; NestedCondition on ConditionalOnRibbonAndEurekaEnabled.OnRibbonAndEurekaEnabledCondition.EurekaBeans @ConditionalOnBean (types: com.netflix.discovery.EurekaClient; SearchStrategy: all) found bean 'eurekaClient'; NestedCondition on ConditionalOnRibbonAndEurekaEnabled.OnRibbonAndEurekaEnabledCondition.Defaults found matching nested conditions @ConditionalOnClass found required class 'com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList', @ConditionalOnBean (types: org.springframework.cloud.netflix.ribbon.SpringClientFactory; SearchStrategy: all) found bean 'springClientFactory', @ConditionalOnProperty (ribbon.eureka.enabled) matched (ConditionalOnRibbonAndEurekaEnabled.OnRibbonAndEurekaEnabledCondition)
小结: RibbonEurekaAutoConfiguration生效
5. EurekaDiscoveryClientConfiguration
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties
@ConditionalOnClass(EurekaClientConfig.class)
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
@ConditionalOnDiscoveryEnabled
@ConditionalOnBlockingDiscoveryEnabled
public class EurekaDiscoveryClientConfiguration {
……
}
- 生效条件:类路径中包含EurekaDiscoveryClientConfiguration类,且服务发现以及阻塞式服务发现功能已启用。
为什么要求阻塞式服务发现?这样客户端在请求服务列表时会直接等待Eureka服务器响应,而不是采用异步或轮询的方式,减少资源损耗。
- 实现:类和属性生效的条件判断的核心方法同上。
- 日志
EurekaDiscoveryClientConfiguration matched:
- @ConditionalOnClass found required class 'com.netflix.discovery.EurekaClientConfig' (OnClassCondition)
- @ConditionalOnProperty (eureka.client.enabled) matched; @ConditionalOnProperty (spring.cloud.discovery.enabled) matched; @ConditionalOnProperty (spring.cloud.discovery.blocking.enabled) matched (OnPropertyCondition)
小结:EurekaDiscoveryClientConfiguration生效。
6. EurekaReactiveDiscoveryClientConfiguration
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(EurekaClientConfig.class)
@ConditionalOnDiscoveryEnabled
@ConditionalOnReactiveDiscoveryEnabled
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureAfter({ EurekaClientAutoConfiguration.class,
ReactiveCompositeDiscoveryClientAutoConfiguration.class })
@AutoConfigureBefore(ReactiveCommonsClientAutoConfiguration.class)
@ImportAutoConfiguration(EurekaClientAutoConfiguration.class)
public class EurekaReactiveDiscoveryClientConfiguration {
……
}
- 生效条件:类路径中包含EurekaClientConfig类且启用了服务发现功能的以及响应式服务发现功能被启用。
- 实现:类和属性生效的条件判断的核心方法同上。
- 日志
EurekaReactiveDiscoveryClientConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.springframework.web.reactive.function.client.WebClient' (OnClassCondition)
小结:EurekaReactiveDiscoveryClientConfiguration不生效
7. LoadBalancerEurekaAutoConfiguration
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties
@ConditionalOnClass(LoadBalancerClientConfigurationRegistrar.class)
@LoadBalancerClients(defaultConfiguration = EurekaLoadBalancerClientConfiguration.class)
@ConditionalOnProperty(name = "eureka.client.enabled", matchIfMissing = true)
public class LoadBalancerEurekaAutoConfiguration {
……
}
- 生效条件:类路径中包含LoadBalancerClientConfigurationRegistrar且eureka客户端被启用。
- 实现:类和属性生效的条件判断的核心方法同上。
- 日志
LoadBalancerEurekaAutoConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientConfigurationRegistrar' (OnClassCondition)
- @ConditionalOnProperty (eureka.client.enabled) matched (OnPropertyCondition)
小结:LoadBalancerEurekaAutoConfiguration生效
最后,来总结下,最终被加载到spring容器中的eureka相关配置类有5个,分别是
- DiscoveryClientOptionalArgsConfiguration:为发现客户端提供了可选参数的配置支持。
- EurekaClientAutoConfiguration:在 Eureka 客户端的自动配置方面发挥着核心作用,确保客户端能够正确地初始化并与 Eureka 服务器交互。
- RibbonEurekaAutoConfiguration:将 Ribbon 与 Eureka 进行整合,实现了服务调用过程中的负载均衡策略。
- EurekaDiscoveryClientConfiguration:负责 Eureka 发现客户端的具体配置,确保客户端能够根据配置正确地注册和发现服务。
- LoadBalancerEurekaAutoConfiguration:对负载均衡与 Eureka 的结合进行自动配置,确保服务调用过程中能够实现高效的负载均衡。