SpringCloud(三):@EnableDiscoveryClient 注解如何实现服务注册与发现

通过前面的文章,我们在每个引导类上都使用了@EnableDiscoveryClient这个注解,这个注解的作用是让该服务放注册中心注册和从注册中心获取其他服务。今天我们就来聊聊@EnableDiscoveryClient注解是如何进行服务注册与服务发现。

@EnableDiscoveryClient 是如何实现服务注册的?

我们首先需要了解 Spring-Cloud-Commons 这个模块,Spring-Cloud-Commons 是 Spring-Cloud 官方提供的一套抽象层,类似于 JDBC 一样,提供了一套规范,具体的实现有实现厂商去根据标准实现,在Finchley版中, Spring-Cloud-Commons 共提供了6个模块标准规范。

  • actuator
  • circuitbreaker
  • discovery
  • hypermedia
  • loadbalancer
  • serviceregistry
    在今天的文章中,我们一起来探讨学习一下 discoveryserviceregistry这两个模块,我们使用 alibaba 的 nacos-discovery 实现来进行学习。

@EnableDiscoveryClient 注解做了什么事?

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(EnableDiscoveryClientImportSelector.class)
public @interface EnableDiscoveryClient {
   

	/**
	 * If true, the ServiceRegistry will automatically register the local server.
	 */
	boolean autoRegister() default true;
}

EnableDiscoveryClient源码可以看出该接口有一个autoRegister()方法默认返回值是true,它还做了一件非常重要的事,引用了EnableDiscoveryClientImportSelector类。为什么说这个类非常重要呢?我们来看看就知道了

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 {
   
			Environment env = getEnvironment();
			if(ConfigurableEnvironment.class.isInstance(env)) {
   
				ConfigurableEnvironment configEnv = (ConfigurableEnvironment)env;
				LinkedHashMap<String, Object> map = new LinkedHashMap<>();
				map.put("spring.cloud.service-registry.auto-registration.enabled", false);
				MapPropertySource propertySource = new MapPropertySource(
						"springCloudDiscoveryClient", map);
				configEnv.getPropertySources().addLast(propertySource);
			}

		}

		return imports;
	}

	@Override
	protected boolean isEnabled() {
   
		return getEnvironment().getProperty(
				"spring.cloud.discovery.enabled", Boolean.class, Boolean.TRUE);
	}

	@Override
	protected boolean hasDefaultFactory() {
   
		return true;
	}

}

将焦点聚集到selectImports()方法上,该类获取了autoRegister 的值。

autoRegister=true 时,将AutoServiceRegistrationConfiguration类添加到自动装配中,系统就会去自动装配AutoServiceRegistrationConfiguration类,在具体的实现中自动装配类都是在这个AutoServiceRegistrationConfiguration类自动装配完成后才装配的,也就是说autoRegister=true就更够实现服务注册

autoRegister=false时,将spring.cloud.service-registry.auto-registration.enabled 设置成了 false,这样跟注册相关的类将不会自动装配,因为自动注册相关的类都有一个条件装配@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true),换句话说如果我们不想该服务注册到注册中心,只是想从注册中心拉取服务,我们只需要引导类上的注解改成@EnableDiscoveryClient(autoRegister = false)

nacos 是如何根据标准去实现服务注册的?

我们先看看在org.springframework.cloud.alibaba.nacos包下的NacosDiscoveryAutoConfiguration

NacosDiscoveryAutoConfiguration类做了些什么?

@Configuration
@EnableConfigurationProperties
@ConditionalOnNacosDiscoveryEnabled
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
@AutoConfigureAfter({
    AutoServiceRegistrationConfiguration.class,
		AutoServiceRegistrationAutoConfiguration.class })
public class NacosDiscoveryAutoConfiguration {
   

	@Bean
	public NacosServiceRegistry nacosServiceRegistry(
			NacosDiscoveryProperties nacosDiscoveryProperties) {
   
		return new NacosServiceRegistry(nacosDiscoveryProperties);
	}

	@Bean
	@ConditionalOnBean(AutoServiceRegistrationProperties.class)
	public NacosRegistration nacosRegistration(
			NacosDiscoveryProperties nacosDiscoveryProperties,
			ApplicationContext context) {
   
		return new NacosRegistration(nacosDiscoveryProperties, context);
	}

	@Bean
	@ConditionalOnBean(AutoServiceRegistrationProperties.class)
	public NacosAutoServiceRegistration nacosAutoServiceRegistration(
			NacosServiceRegistry registry,
			AutoServiceRegistrationProperties autoServiceRegistrationProperties,
			NacosRegistration registration) {
   
		return new NacosAutoServiceRegistration(registry,
				autoServiceRegistrationProperties, registration);
	
  • 20
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值