准备做个Spring Cloud源码分析系列, 作为Spring Cloud的源码分析笔记.
这一篇是Eureka的客户端.
两种方式, 最终的实现基本一样.
使用 @EnableEurekaClient
注解显示的指定使用Eureka作为服务发现的实现, 并实例化 EurekaClient
实例. 实际上使用的是 @EnableDiscoveryClient
注解.
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @EnableDiscoveryClient public @interface EnableEurekaClient { }
使用 @EnableDiscoveryClient
注解来配置服务发现的实现.
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Import(EnableDiscoveryClientImportSelector.class) public @interface EnableDiscoveryClient { }
EnableDiscoveryClient
注解的作用主要是用来引入 EnableDiscoveryClientImportSelector
@Order(Ordered.LOWEST_PRECEDENCE - 100) public class EnableDiscoveryClientImportSelector extends SpringFactoryImportSelector<EnableDiscoveryClient> { @Override protected boolean isEnabled(){ return new RelaxedPropertyResolver(getEnvironment()).getProperty( "spring.cloud.discovery.enabled", Boolean.class, Boolean.TRUE); } @Override protected boolean hasDefaultFactory(){ return true; } }
EnableDiscoveryClientImportSelector
继承了 SpringFactoryImportSelector
并指定了泛型 EnableDiscoveryClient
. 这里的泛型是重点
.
public abstract class SpringFactoryImportSelector<T> implements DeferredImportSelector, BeanClassLoaderAware, EnvironmentAware { private ClassLoader beanClassLoader; private Class<T> annotationClass; protected SpringFactoryImportSelector(){ this.annotationClass = (Class<T>) GenericTypeResolver .resolveTypeArgument(this.getClass(), SpringFactoryImportSelector.class); } public String[] selectImports(AnnotationMetadata metadata) { ... } }
这里只截取了部分变量和方法
SpringFactoryImportSelector
是spring cloud common包中的一个抽象类, 主要作用是检查泛型T是否有指定的factory实现, 即spring.factories中有对应类的配置.
在 spring-cloud-netflix-eureka-client.jar!/META-INF/spring.factories
中 EnableDiscoveryClient
的指定factory实现是
org.springframework.boot.autoconfigure.EnableAutoConfiguration=/ org.springframework.cloud.netflix.eureka.config.EurekaClientConfigServerAutoConfiguration,/ org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceAutoConfiguration,/ org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration,/ org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration org.springframework.cloud.bootstrap.BootstrapConfiguration=/ org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceBootstrapConfiguration org.springframework.cloud.client.discovery.EnableDiscoveryClient=/ org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration
同时 EnableAutoConfiguration
中包含了 org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration
, EurekaClientAutoConfiguration
会为 EurekaDiscoveryClientConfiguration
的实例依赖进行初始化, 如EurekaClient. EurekaClient在构造时会启动一个HeartBeat线程, 线程在运行的时候会做renew的操作, 将Application的信息注册更新到Eureka的服务端.
@Configuration @EnableConfigurationProperties @ConditionalOnClass(EurekaClientConfig.class) @ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true) @CommonsLog public class EurekaDiscoveryClientConfigurationimplements SmartLifecycle,Ordered{ ... }