目录
- 0 版本
- 1 Spring Boot
- 2 Spring-Cloud-Commons
- 3 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 {
这个注解 @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;
}
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;
}
}
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 {
}
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 {
};
}
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)))
// 过滤空的class
.filter((type) -> void.class != type)
// 返回set
.collect(Collectors.toSet());
}
static void registerInfrastructureBeans(BeanDefinitionRegistry registry) {
ConfigurationPropertiesBindingPostProcessor.register(registry);
BoundConfigurationProperties.register(registry);
}
// 注册方法验证排除过滤器
static void registerMethodValidationExcludeFilter(BeanDefinitionRegistry registry)