说到spring clound 是如何集成 spring clound alibaba 的,就绕不开spring 的事件发布机制,没错,spring 是通过它的事件发布机制来集成 spring cloung alibaba nacos, 从而实现服务向 nacos 注册的。
JDK对事件监听机制的支持
spring 的事件发布机制的根本原理是基于 观察者模式实现的,在jdk的基础jar包中,提供的观察者模式的最基本实现。它提供了两个基础类。
EventObject: 定义事件类型, 里面可以传入事件源
EventListener:事件监听器,监听事件
需要你自己定义事件发布器,在里面注册监听器,发布事件信息。
spring 的事件发布机制
spring的事件发布机制也是基于在上面所提到的两个基本类来实现的,当然,要比jdk的复杂得多。
首先,定义了ApplicationEvent 对象,该对象继承 EventObject 接口
再定义了一个ApplicationListener ,继承EventListener 对象, 同时,定义了一个接受事件发布监听的接口,该接口要求传入监听的事件类型。
定义了一个事件发布器, 用于发布定义的各种spring事件。但是其实真正发布spring事件的不是这个类,是另外一个类 ApplicationEventMulticaster。看了下有关spring的源码,spring一般都是要不直接调用ApplicationEventMulticaster.multicastEvent() 方法,要不就是通过 ApplicationEventPublisher.publishEvent(),再在里面调用ApplicationEventMulticaster.multicastEvent() 来实现对事件的发布。
spring cloud 如何实现向Nacos 进行客户端服务注册
在Nacos 服务注册发现的包下面,有一个registry包,包下有如下方法,不难想象,实现服务自动注册就是由以下的类所完成的。
首先我们先看NacosAutoServiceRegistration类,类中的关系如下:
NacosAutoServiceRegistration 继承自 AbstractAutoServiceRegistration 类,而这个实现了 ApplicationListener 接口,所以接下来我们看下这个类所实现的监听方法。
onApplicationEvent() 方法调用了bind()方法, bind()再调用了 start(), start() 再调用了register(), 实现注册的逻辑就在这个方法里面。
让我们看看register(),
可以看到, AbstractAutoServiceRegistration 类里依赖了 ServiceRegistry, 这是一个接口,NacosServiceRegistry 实现了此接口,所以,上面的 register()最后就会调用到 NacosServiceRegistry 的 register()
接下来,让我们看看NacosServiceRegistry 的 register()方法,可以看到,在这方法中,获取到 serviceId 和 所属group,构建了一个 Intance对象,这个对象就是代表此服务实例。
然后再调用 registerInstance()方法。
在这个方法中,首先判断了下是不是临时节点,如果是临时节点的话,就构建心跳信息,然后调用 addBeatInfo()向服务端发送心跳信息。
再就是调用 registerService(),构建参数列表,然后向服务器发送注册信息。
我们打开nacos 的官网,可以看到,官网上服务发现就是向nacos服务器发送以下这个请求,与我们看源码看到的一样。
那NacosAutoServiceRegistration 和 NacosRegistration 是好久注册的呢,这个我们就要看 NacosServiceRegistryAutoConfiguration类,在这个类中,实现了对这两个类的注册。
在AbstractAutoServiceRegistration中,监听的事件类型为 WebServerInitializedEvent
其实现类有2个, 一个是 ServletWebServerInitializedEven、ReactiveWebServerInitializedEventt,我们是web项目,所以只看 ServletWebServerInitializedEven就行了,单击它,可以看到调用它的地方只有一个,就是当servlet 容器完成刷新时,发布了ServletWebServerInitializedEven 事件,最终被 NacosAutoServiceRegistration 监听到,然后完成了向服务端发送心跳和注册的过程。
至此,nacos 向服务端完成注册的流程就已经讲完了!