Springboot在启动的时候会自动读取spring-cloud-commons 包下/META-INF/spring.factories文件中的以下两个有关服务注册与发现的配置类
# AutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration,\
org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration,\
org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration,\
org.springframework.cloud.client.discovery.composite.reactive.ReactiveCompositeDiscoveryClientAutoConfiguration,\
org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration,\
org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration,\
org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryClientAutoConfiguration,\
其中AutoServiceRegistrationAutoConfiguration配置类主要功能是通过自动注入的方式来判断是否具备自动注册的具体实现
@Configuration(proxyBeanMethods = false)
@Import(AutoServiceRegistrationConfiguration.class)
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled",
matchIfMissing = true)
public class AutoServiceRegistrationAutoConfiguration {
//注人自动注册的实现类
@Autowired(required = false)
private AutoServiceRegistration autoServiceRegistration;
//自动注册相应配置
@Autowired
private AutoServiceRegistrationProperties properties;
@PostConstruct
protected void init() {
//如果环境中没有AutoServiceRegistration的具体实现,并且设置了
//当AutoServiceRegistration不存在时则快速失败为true,则抛出异常
if (this.autoServiceRegistration == null && this.properties.isFailFast()) {
throw new IllegalStateException("Auto Service Registration has "
+ "been requested, but there is no AutoServiceRegistration bean");
}
}
}
对于具体的服务注册组件在与springcloud集成的时候要求提供AutoServiceRegistration的实现类来完成自动注册功能(具体完成注册的逻辑可自行实现),例如:EurekaAutoServiceRegistration、ConsulAutoServiceRegistration。
某些地方可以会说要添加@EnableDiscoveryClient注解来完成服务的自动发现功能,其实该注解的目的只是为了加载AutoServiceRegistrationConfiguration配置类,或者通过设置注解的autoRegister的值来控制是否启动自动注册。由上面的分析得知,其实在@EnableAutoConfiguration注解执行时从spring.factories中就会自动读取到AutoServiceRegistrationAutoConfiguration配置类,所以根本不需要使用@EnableDiscoveryClient注解。
spring-cloud-commons 中对服务的注册进行了以下的几个抽象
接口/抽象类 | 类型 | 说明 |
---|---|---|
ServiceInstance | 接口 | 表示服务发现系统中服务的实例,包含了IP,端口等 |
Registration | 接口 | 继承自ServiceInstance的接口,用于ServiceRegistry使用的标记接口 |
ServiceRegistry<R extends Registration> | 接口 | 服务注册和注销接口 |
AutoServiceRegistration | 接口 | 完成服务的自动注册接口(引用ServiceRegistry实例) |
继承关系如下图
Eureka的自动注册
EurekaClientAutoConfiguration配置类中重点是完成了EurekaRegistration ,EurekaServiceRegistry ,EurekaAutoServiceRegistration对象的构造,在该配置类执行完后,其配置对象AutoServiceRegistrationAutoConfiguration将会被执行,从而完成自动的注册功能。
@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 {
private ConfigurableEnvironment env;
public EurekaClientAutoConfiguration(ConfigurableEnvironment env) {
this.env = env;
}
//创建Eureka用于注册的对象【重点】
@Bean
public EurekaServiceRegistry eurekaServiceRegistry() {
return new EurekaServiceRegistry();
}
//创建Eureka的服务自动注册类【重点】
@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
@ConditionalOnProperty(
value = "spring.cloud.service-registry.auto-registration.enabled",
matchIfMissing = true)
public EurekaAutoServiceRegistration eurekaAutoServiceRegistration(
ApplicationContext context, EurekaServiceRegistry registry,
EurekaRegistration registration) {
return new EurekaAutoServiceRegistration(context, registry, registration);
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingRefreshScope
protected static class EurekaClientConfiguration {
@Autowired
private ApplicationContext context;
创建服务注册对象【重点】
@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
@ConditionalOnProperty(
value = "spring.cloud.service-registry.auto-registration.enabled",
matchIfMissing = true)
public EurekaRegistration eurekaRegistration(EurekaClient eurekaClient,
CloudEurekaInstanceConfig instanceConfig,
ApplicationInfoManager applicationInfoManager, @Autowired(
required = false) ObjectProvider<HealthCheckHandler> healthCheckHandler) {
return EurekaRegistration.builder(instanceConfig).with(applicationInfoManager)
.with(eurekaClient).with(healthCheckHandler).build();
}
}
}
注意:在EurekaAutoServiceRegistration内部会监听ApplicationContext的启动完成事件,然后执行了start()方法完成了服务的注册。