所有文章
https://www.cnblogs.com/lay2017/p/11908715.html
正文
前面的幾篇文章中,我們從eureka Server端的角度看了看eureka的幾個核心要點。本文開始,將從eureka client端的角度了解它。同樣的,基於spring cloud的eureka client將先看看它的自動配置。
@EnableDiscoveryClient開關自動注冊服務
我們先從注解開始,注解意味着開啟了eureka client
@SpringBootApplication @EnableDiscoveryClient public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
打開注解看看,你會發現這里的autoRegister默認值是true。也就是說,如果你配置為false,那么就不會自動注冊
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Import(EnableDiscoveryClientImportSelector.class) public @interface EnableDiscoveryClient { /** * If true, the ServiceRegistry will automatically register the local server. * @return - {@code true} if you want to automatically register. */ boolean autoRegister() default true; }
稍微不同於Server端的是,client端不是直接引入一個Configuration而是通過一個ImportSelector來導入類。跟進EnableDiscoveryClientImportSelector類
@Order(Ordered.LOWEST_PRECEDENCE - 100) public class EnableDiscoveryClientImportSelector extends SpringFactoryImportSelector<EnableDiscoveryClient> { @Override public String[] selectImports(AnnotationMetadata metadata) { String[] imports = super.selectImports(metadata); AnnotationAttributes attributes = AnnotationAttributes.fromMap( metadata.getAnnotationAttributes(getAnnotationClass().getName(), true)); boolean autoRegister = attributes.getBoolean("autoRegister"); if (autoRegister) { List<String> importsList = new ArrayList<>(Arrays.asList(imports)); importsList.add("org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration"); imports = importsList.toArray(new String[0]); } else { // ... } return imports; } }
selectImports方法主要就是導入了一個類AutoServiceRegistrationCofiguration,我們看看導入的這個類干了啥
@Configuration @EnableConfigurationProperties(AutoServiceRegistrationProperties.class) @ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) public class AutoServiceRegistrationConfiguration { }
好吧,只是簡單的加載了一些屬性,如果沒有配置該屬性那么將會是默認值(eureka啟動的大部分默認值都是true,所以你會發現,即使沒有添加@EnableDiscoveryClient注解,使用默認值也是可以的)。
EurekaClientAutoConfiguration自動配置客戶端
EurekaClientAutoConfiguration這個自動配置類就比較可怕了,代碼顯得比服務端多了不少。
@Configuration @EnableConfigurationProperties @ConditionalOnClass(EurekaClientConfig.class) @Import(DiscoveryClientOptionalArgsConfiguration.class) @ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true) @ConditionalOnDiscoveryEnabled @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 { // ... }
注解比較多,但是沒那么復雜。就是加載一些附加的配置,以及判斷一下是否開始自動配置。下面,我們再看看內部添加了哪些東西(只關注幾個核心的)
配置當前實例信息
配置實例信息包含很多,不過核心的無非就是名稱、唯一標識、IP地址、端口等等
@Bean @ConditionalOnMissingBean(value = EurekaInstanceConfig.class, search = SearchStrategy.CURRENT) public EurekaInstanceConfigBean eurekaInstanceConfigBean(InetUtils inetUtils, ManagementMetadataProvider managementMetadataProvider) { // ... EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(inetUtils); instance.setNonSecurePort(serverPort); instance.setInstanceId(getDefaultInstanceId(env)); instance.setPreferIpAddress(preferIpAddress); instance.setSecurePortEnabled(isSecurePortEnabled); if (StringUtils.hasText(ipAddress)) { instance.setIpAddress(ipAddress); } // ... setupJmxPort(instance, jmxPort); return instance; }
負責注冊的Bean
@Bean public EurekaServiceRegistry eurekaServiceRegistry() { return new EurekaServiceRegistry(); }
自動注冊調用的Bean
@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); }
Eureka待注冊的對象
這個對象會包含上面的eurekaInstanceIConfigBean
@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(); }
總結
eureka客戶端的自動配置,其實就是做了一些注冊等操作之前的准備。准備實例信息,配置eureka框架的東西。代碼很多,但是邏輯並不復雜。下一篇文章,我們將看看如何自動注冊。