1.自动装配原则下client加载

spring cloud 启动顺序控制_spring cloud

配置类简单描述:

1.EurekaClientConfigServerAutoConfiguration :如果配置服务器和eureka 实例在同一个服务上,这里需要处理一下服务实例的元数据信息
2.EurekaDiscoveryClientConfigServiceAutoConfiguration:eureka 与 配置中心的联合使用处理
3.EurekaClientAutoConfiguration:eureka client 服务启动的核心
4.RibbonEurekaAutoConfiguration:eureka 与 ribbon整合的核心
5.EurekaDiscoveryClientConfiguration:eureka client配置类
6.EurekaDiscoveryClientConfigServiceBootstrapConfiguration: 通过服务发现找到配置服务器的启动类

2.这里我们首先看看eureka client配置类EurekaDiscoveryClientConfiguration

2.1 eureka 启动开关判断

这里我们看到Marker,这个是不是很眼熟,跟Eureka server 服务启用的的标识类名称一致。

spring cloud 启动顺序控制_spring cloud 启动顺序控制_02

但是有个区别就是,这里只需要开启eureka.client.enabled = true 就会自动开启eureka client。而不需要向eureka server一样,需要@EnableEurekaServer来开启。

2.2 eureka client 配置刷新

spring cloud 启动顺序控制_spring cloud_03

2.3 eureka client 之actuator检查

将eureka client的健康状态交给actuator监控采集中心

spring cloud 启动顺序控制_java_04

3. EurekaClientAutoConfiguration eureka client 启动核心类

3.1 令人头疼的注解堆

@Configuration
@EnableConfigurationProperties // 开启从springboot 配置中读取配置信息的功能
@ConditionalOnClass(EurekaClientConfig.class) // 启动条件1: EurekaClientConfig这个类要存在
@Import(DiscoveryClientOptionalArgsConfiguration.class) // 这个跟spring.factories重复了
@ConditionalOnBean(EurekaDiscoveryClientConfiguration.Marker.class) // 这个在EurekaDiscoveryClientConfiguration已经初始化到spring容器中了
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true) // 跟EurekaDiscoveryClientConfiguration启用的判断条件一直
// 在这里类之前加载
@AutoConfigureBefore({ NoopDiscoveryClientAutoConfiguration.class,
		CommonsClientAutoConfiguration.class, ServiceRegistryAutoConfiguration.class })
// 在这些类之后加载
@AutoConfigureAfter(name = {"org.springframework.cloud.autoconfigure.RefreshAutoConfiguration",
		"org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration",
		"org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration"})
public class EurekaClientAutoConfiguration {

这里总结一下:

  1. 通过ConditionalOnClass和ConditionalOnBean和ConditionalOnProperty来判断是否加载eureka client
  2. 通过AutoConfigureBefore和AutoConfigureAfter进行配置加载顺序编排

3.2 初始化Eureka 服务实例配置信息

spring cloud 启动顺序控制_java_05

3.3 初始化DiscoveryClient的增强类(EurekaDiscoveryClient)

spring cloud 启动顺序控制_eureka_06

但是这里的EurekaDiscoveryClient只是一个增强类,具体的eureka client 是作为参数传递进来的那个client,这个的初始化尤为关键。

3.4 初始化服务注册处理类

@Bean
	public EurekaServiceRegistry eurekaServiceRegistry() {
		return new EurekaServiceRegistry();
	}

3.5 初始化自动服务注册处理类

在spring容器加载完成之后,自动端口检测和服务注册,并发布服务实例注册事件

这个也是一个事件监听器:

**WebServerInitializedEvent :**web容器初始化完成事件,这个时候就知道我们的web服务监听了哪个端口,这样eureka 提供服务的端口也就指定了。

ContextClosedEvent:spring上下文关闭事件,这个时候会执行服务下线操作。这些都是spring的各个关键阶段对外发布的事件,这里对其进行了处理。

@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);
	}

4. EurekaClientAutoConfiguration的内部类EurekaClientConfiguration在干啥?

4.1 初始化 eureka client (重点)

这个是DiscoveryClient的子类,是整个Eureka Client的核心。其走的初始化流程是eureka原生的DiscoveryClient。在之前的eureka server原生源码中已经讲过。这里不再赘述。这里面的东西很多,想了解的可以去瞅瞅。

@Bean(destroyMethod = "shutdown")
		@ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)
		public EurekaClient eurekaClient(ApplicationInfoManager manager, EurekaClientConfig config) {
			return new CloudEurekaClient(manager, config, this.optionalArgs,
					this.context);
		}

4.2 初始化服务实例管理器

@Bean
		@ConditionalOnMissingBean(value = ApplicationInfoManager.class, search = SearchStrategy.CURRENT)
		public ApplicationInfoManager eurekaApplicationInfoManager(
				EurekaInstanceConfig config) {
			InstanceInfo instanceInfo = new InstanceInfoFactory().create(config);
			// 将自身服务实例交给服务实例管理器管理
			return new ApplicationInfoManager(config, instanceInfo);
		}

4.3 eureka 注册信息存储器

这里面存储了eurekaClient,eureka client配置信息,自身服务实例管理器,健康检查器等

@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();
		}

5.EurekaClientAutoConfiguration的内部类RefreshableEurekaClientConfiguration在干啥?

这个类主要是当配置文件发生变化后,eureka client 进行重新创建,服务进行重新注册,心跳信息进行重新包装,服务实例管理器ApplicationInfoManager插入最新实例信息,包括服务实例注册信息存储器EurekaRegistration都要重新构造一遍。

这就是spring cloud eureka client 对配置中心配置自动刷新的支持。

6.小结

eureka client的初始化内容比较多,而且做了比较多的一个封装。其中为了配合@RefreshScope 自动刷新也做了很多事情。总的来说跟eureka client 原生的初始化没有太大区别,都是走的DiscoveryClient的构造函数进行初始化的,这个是核心。其他的都是为了配合spring 做了一些变动。比如InstanceRegistry,这个就是对PeerAwareInstanceRegistryImpl的封装,在这里加入了spring相关的东西。
总而言之,spring cloud的源码阅读起来,其实是比eureka server原生要麻烦一点的。毕竟相互注入的对象初始化比较难找