五、eureka客户端自动配置

所有文章

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框架的东西。代码很多,但是逻辑并不复杂。下一篇文章,我们将看看如何自动注册。

原文地址:https://www.cnblogs.com/lay2017/p/11922547.html