看了Eureka系列、Ribbon系列、Feign系列、Zuul系列,我相信你們應該知道怎麼找到看源碼的入口了,一個是須要用的註解,一個是spring.factories。咱們仍是從註解先來。spring
這個註解作了兩件事,一個是import了EnableDiscoveryClientImportSelector,另一個就是默認autoRegister爲true,開啓自動註冊。segmentfault
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Import(EnableDiscoveryClientImportSelector.class) public @interface EnableDiscoveryClient { boolean autoRegister() default true; }
EnableDiscoveryClientImportSelector的selectImports方法,經過上面的autoRegister來判斷,若是爲true,則import了AutoServiceRegistrationConfiguration,若是爲false,pring.cloud.service-registry.auto-registration.enabled設置爲false。這個參數決定了是否引入自動註冊。tomcat
@Override public String[] selectImports(AnnotationMetadata metadata) { // 其餘略 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 { // 其餘略 // spring.cloud.service-registry.auto-registration.enabled設置爲false map.put("spring.cloud.service-registry.auto-registration.enabled", false); // 其餘略 } return imports; }
註解的部分看完了,咱們開始看spring.factories。首先是NacosServiceAutoConfiguration。
這裏只加載了NacosServiceManager,是service核心管理類,NamingService就是他管理的。ide
這個是用於服務發現的,他加載了兩個類,NacosDiscoveryProperties和NacosServiceDiscovery。
NacosDiscoveryProperties是配置類,咱們配置註冊中心的信息就是在這裏配置。
NacosServiceDiscovery主要是用於服務發現。ui
NacosServiceRegistryAutoConfiguration,這個是用於自動註冊的。
咱們看到他上面的註解信息,@AutoConfigureAfter
確保AutoServiceRegistrationConfiguration先加載,而後判斷spring.cloud.service-registry.auto-registration.enabled是否爲true,爲true才能夠加載。因此上面@EnableDiscoveryClient的autoRegister若是設置爲false,則不加載。
由於spring.cloud.service-registry.auto-registration.enabled默認是true的,因此@EnableDiscoveryClient其實不引入,也是能夠加載NacosServiceRegistryAutoConfiguration。this
@Configuration(proxyBeanMethods = false) @EnableConfigurationProperties @ConditionalOnNacosDiscoveryEnabled @ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) @AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class, AutoServiceRegistrationAutoConfiguration.class, NacosDiscoveryAutoConfiguration.class }) public class NacosServiceRegistryAutoConfiguration
這個類會加載NacosServiceRegistry、NacosRegistration、NacosAutoServiceRegistration。NacosServiceRegistry、NacosRegistration會注入到NacosAutoServiceRegistration。
NacosServiceRegistry主要用於註冊、取消註冊。
NacosRegistration是當前實例的信息,好比實例名稱、實例id、端口、ip等。
NacosAutoServiceRegistration繼承了NacosAutoServiceRegistration,NacosAutoServiceRegistration又繼承了AbstractAutoServiceRegistration。AbstractAutoServiceRegistration實現了ApplicationListener<WebServerInitializedEvent>接口,經過WebServerInitializedEvent就知道了,當tomcat啓動成功後,會調用onApplicationEvent(WebServerInitializedEvent event)方法。這個方法會實現註冊操做,後面再來說解。spa
這裏加載了兩個類,DiscoveryClient和NacosWatch。
DiscoveryClient主要用於示例獲取和服務獲取。
NacosWatch實現了SmartLifecycle接口,因此會調用start和stop方法。
start方法主要是加入NamingEvent監聽、獲取NamingService、註冊監聽、發佈HeartbeatEvent事件。code
@Override public void start() { // 啓動的時候,加入NamingEvent監聽 if (this.running.compareAndSet(false, true)) { EventListener eventListener = listenerMap.computeIfAbsent(buildKey(), event -> new EventListener() { @Override public void onEvent(Event event) { // 更新本地的Instance if (event instanceof NamingEvent) { List<Instance> instances = ((NamingEvent) event) .getInstances(); Optional<Instance> instanceOptional = selectCurrentInstance( instances); instanceOptional.ifPresent(currentInstance -> { resetIfNeeded(currentInstance); }); } } }); // 獲取NamingService NamingService namingService = nacosServiceManager .getNamingService(properties.getNacosProperties()); try { // 註冊監聽 namingService.subscribe(properties.getService(), properties.getGroup(), Arrays.asList(properties.getClusterName()), eventListener); } catch (Exception e) { log.error("namingService subscribe failed, properties:{}", properties, e); } //發佈HeartbeatEvent事件 this.watchFuture = this.taskScheduler.scheduleWithFixedDelay( this::nacosServicesWatch, this.properties.getWatchDelay()); } }