当前位置:   article > 正文

Spring-Cloud-Starter-Alibaba-Nacos-Discovery 源码分析

spring-cloud-starter-alibaba-nacos-discovery

0 版本

  • spring-cloud-starter-alibaba-nacos-discovery 2021.0.1.0
  • spring-cloud-commons 3.1.1
  • spring-boot-starter-web 2.6.3

1 Spring Boot

1.1.@EnableDiscoveryClient , 启用服务发现

通过在Aplication 处添加该注解, 启用服务发现:

@SpringBootApplication
@EnableDiscoveryClient // 启用服务发现
public class MsGatewayApplication {
   
  • 1
  • 2
  • 3
  • 4

这个注解 @EnableDiscoveryClient 是在Spring-Cloud-Commons里定义的

2 Spring-Cloud-Commons

2.1 @EnableDiscoveryClient: 通过注解导入 EnableDiscoveryClientImportSelector

查看该注解定义, 可以看到 @Import({EnableDiscoveryClientImportSelector.class}) ,这个注解会在启动时, 自动注入 EnableDiscoveryClientImportSelector


@Target({
   ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({
   EnableDiscoveryClientImportSelector.class}) // 通过注解导入 EnableDiscoveryClientImportSelector
public @interface EnableDiscoveryClient {
   
    boolean autoRegister() default true;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2.1.1 EnableDiscoveryClientImportSelector 启用服务发现客户端导入选择器

EnableDiscoveryClientImportSelector 的主要功能是导入需要的 AutoServiceRegistrationConfiguration (自动服务注册配置类) 或者 修改环境变量,这取决于 @EnableDiscoveryClient 里的 autoRegister 参数

根据 autoRegister(默认为true)判断:
 
如果为 true :     importsList.add(“org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration”) 是在引用列表里添加 org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration , 这个类是在 spring-coud-commons 项目里定义的
   
如果为 false :
map.put(“spring.cloud.service-registry.auto-registration.enabled”, false) 在环境变量中将 自动注册 设为 false
 

@Order(2147483547)
public class EnableDiscoveryClientImportSelector extends SpringFactoryImportSelector<EnableDiscoveryClient> {
   
    public EnableDiscoveryClientImportSelector() {
   
    }

    public String[] selectImports(AnnotationMetadata metadata) {
   
        String[] imports = super.selectImports(metadata);
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(this.getAnnotationClass().getName(), true));
        boolean autoRegister = attributes.getBoolean("autoRegister");
        // 是否自动注册服务 EnableDiscoveryClient.autoRegister default true
        if (autoRegister) {
   
            // 引用列表
	        List<String> importsList = new ArrayList(Arrays.asList(imports));
	        // 调用 spring-cloud-commons  里的 AutoServiceRegistrationConfiguration (自动服务注册配置)
            importsList.add("org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration");
            imports = (String[])importsList.toArray(new String[0]);
        } else {
   
            Environment env = this.getEnvironment();
            if (ConfigurableEnvironment.class.isInstance(env)) {
   
                ConfigurableEnvironment configEnv = (ConfigurableEnvironment)env;
                LinkedHashMap<String, Object> map = new LinkedHashMap();
                // 配置 spring.cloud.service-registry.auto-registration.enabled 为false,不启用自动注册服务
                map.put("spring.cloud.service-registry.auto-registration.enabled", false);
                MapPropertySource propertySource = new MapPropertySource("springCloudDiscoveryClient", map);
	            // 添加到环境变量
                configEnv.getPropertySources().addLast(propertySource);
            }
        }

        return imports;
    }
  
    // 根据 配置项 spring.cloud.discovery.enabled 判断是否启用服务发现,该配置项默认为true
    protected boolean isEnabled() {
   
        // 从环境变量中获取 spring.cloud.discovery.enabled  的布尔值,并且默认返回TRUE
        return (Boolean)this.getEnvironment().getProperty("spring.cloud.discovery.enabled", Boolean.class, Boolean.TRUE);
    }

    protected boolean hasDefaultFactory() {
   
        return true;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

2.2 AutoServiceRegistrationConfiguration 自动服务注册配置

@EnableConfigurationProperties(AutoServiceRegistrationProperties.class) :
该注解的意思是启用配置类 AutoServiceRegistrationProperties
 
@ConditionalOnProperty(value = “spring.cloud.service-registry.auto-registration.enabled”, matchIfMissing = true):
spring.cloud.service-registry.auto-registration.enabled 的配置项为 true 的时候该类才会启用, 属性 matchIfMissing = true 的意思是假如没有对该项进行配置, 则默认情况下相当于 true,也会启用该类

/**
 * @author Spencer Gibb
 */
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(AutoServiceRegistrationProperties.class) // 启用配置 AutoServiceRegistrationProperties
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)  // spring.cloud.service-registry.auto-registration.enabled 的配置项为true的时候,才会启用, matchIfMissing = true 为该配置项如果未配置,也会启用该类
public class AutoServiceRegistrationConfiguration {
   

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2.2.1 @EnableConfigurationProperties, 启用配置属性

AutoServiceRegistrationConfiguration @Import(EnableConfigurationPropertiesRegistrar.class):
导入了 EnableConfigurationPropertiesRegistrar (一个关于启用属性配置的注册器),该注册器会将 @EnableConfigurationProperties 里的 Class<?>[] value() 进行bean注册 (即对 AutoServiceRegistrationProperties 进行bean注册)

/**
 * Enable support for {@link ConfigurationProperties @ConfigurationProperties} annotated
 * beans. {@code @ConfigurationProperties} beans can be registered in the standard way
 * (for example using {@link Bean @Bean} methods) or, for convenience, can be specified
 * directly on this annotation.
 *
 * @author Dave Syer
 * @since 1.0.0
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EnableConfigurationPropertiesRegistrar.class)
public @interface EnableConfigurationProperties {
   
	
	// 验证器 BEAN 名称 
	/**
	 * The bean name of the configuration properties validator.
	 * @since 2.2.0
	 */
	String VALIDATOR_BEAN_NAME = "configurationPropertiesValidator";

	// 接收一个数组,数组类型为ClassType
	/**
	 * Convenient way to quickly register
	 * {@link ConfigurationProperties @ConfigurationProperties} annotated beans with
	 * Spring. Standard Spring Beans will also be scanned regardless of this value.
	 * @return {@code @ConfigurationProperties} annotated beans to register
	 */
	Class<?>[] value() default {
   };

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

2.2.3 EnableConfigurationPropertiesRegistrar

AutoServiceRegistrationProperties 是怎么被引入呢
这类实现了接口 ImportBeanDefinitionRegistrar , 重写了registerBeanDefinitions 方法,它在这里将之前的 AutoServiceRegistrationProperties 通过 ConfigurationPropertiesBeanRegistrar 注册到容器

/**
 * {@link ImportBeanDefinitionRegistrar} for
 * {@link EnableConfigurationProperties @EnableConfigurationProperties}.
 *
 * @author Phillip Webb
 * @author Andy Wilkinson
 */
class EnableConfigurationPropertiesRegistrar implements ImportBeanDefinitionRegistrar {
   
 
	private static final String METHOD_VALIDATION_EXCLUDE_FILTER_BEAN_NAME = Conventions
			.getQualifiedAttributeName(EnableConfigurationPropertiesRegistrar.class, "methodValidationExcludeFilter");

	
	// 注册
	@Override
	public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
   
		registerInfrastructureBeans(registry);
		registerMethodValidationExcludeFilter(registry);
		// new 一个ConfigurationPropertiesBean注册器
		ConfigurationPropertiesBeanRegistrar beanRegistrar = new ConfigurationPropertiesBeanRegistrar(registry);
	
		getTypes(metadata).forEach(beanRegistrar::register);
		/* 类似:依次注册 getTypes 返回的Class集 
		getTypes(metadata).forEach( (item) -> {
			beanRegistrar.register(item)
		} )
		*/
	}

	// 获取EnableConfigurationProperties集
	private Set<Class<?>> getTypes(AnnotationMetadata metadata) {
   
		return metadata.getAnnotations().stream(EnableConfigurationProperties.class)
				// 合并
				.flatMap((annotation) -> Arrays.stream(annotation.getClassArray(MergedAnnotation.VALUE)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/458317?site
推荐阅读
相关标签
  

闽ICP备14008679号