目标
-
soul-bootstrap 端 Nacos 启动流程
- pom 依赖配置
- yml 配置
- 初始化分析
Nacos 数据如何接收消息发布事件
拿到数据之后如何处理
Java Interface将接口作为参数传递
Soul-Bootstrap端Nacos启动流程
pom依赖配置
<dependency>
<groupId>org.dromara</groupId>
<artifactId>soul-spring-boot-starter-sync-data-nacos</artifactId>
<version>${project.version}</version>
</dependency>
- 自定义Starter NacosSyncDataConfiguration 初始化,通过ObjectProvider查找依赖Bean
- 创建ConfigService
我们知道Nacos三元素确定唯一,所以这里面ConfigService就是制定三元素和一些地址信息
yml配置
初始化分析
下面分析下Nacos初始化流程,通过调用 watcherData
方法,使用Nacos提供的 Listener
来注册当Nacos发布配置时候,可以监听到事件。这里面巧妙的设计使用了interface 作为参数将不同种配置发生变化分别去执行不同的处理Function。
科普下:
接口是Java编程语言中的一种抽象类型,是抽象方法的集合,通常以interface来声明,所以接口不是类,尽管写法相似。
一个类通过实现接口的方式来继承接口的方法。
除非实现接口的类是抽象,否则该类要定义接口中所有方法。
最后一句,也就解释了,soul中为什么很多interface,都会紧跟着一个abstract,只是为了实现N个继承的实际业务类的公共方法。
oc.change()
定义好listener之后下面进行绑定 dataId 与 listener。
LISTENERS 进行存储dataId 与对应的事件监听器
Nacos 数据如何接收消息发布事件
初始化时候将不同的dataId绑定到不同的updateXXMap,等待admin数据发生变动,自动触发listener
拿到数据之后如何处理
这里我们拿plugin解析。拿到数据变化之后,先序列化成List,然后循环一次的先发送批量解绑事件给关心此数据的Plugin,然后在绑定,从这里我们可以看出,这里面采用的是批量操作。
Java Interface 将接口作为参数传递
public class A {
private TestInterface test;
public A(TestInterface test) {
this.test = test;
doSth();
}
public void doSth() {
test. systemStr("this is a message!");
}
}
public Interface TestInterface(){
void systemStr(String str);
}
public class B implement TestInterface{
public static void main(String[] args) {
new A(new B());
}
@Override
public void systemStr(String str) {
System.out(str);
}
}
- 看下这两个类,一个是接口,他们的关系是什么?
class B 作为程序入口类,实现了interface TestInterface,并定义了接口中的systemStr
主方法main()中实例化class A,并将自身class B的实例化对象传入。
在class A中定义一个接口TestInterface类型的成员变量 test,一个具体的方法doSth()
其构造方法接受主方法中传来的数据并初始化成员变量test
doSth方法执行方法systemStr()
- class A的构造定义了TestInterface,为什么传入ClassB实例也可以
这里面涉及到Java 自动转型,TestInterface test 由编译器自动向下转型为classB,实际执行的方法是由classB 继承自testInterface并定义的systemcStr()方法。虽然接受的类型为TestInterface,但是接口不能实例化,所以我们要定一个类来实现接口。并将这个类型传递过去。
所以我们可以定义classA的构造方法接受类型为classB
匿名内部类的lambda语法
- 定义
watcherData(final String dataId, final OnChange oc);
interface OnChange(){
void change();
}
- 调用
watcherData(PLUGIN_DATA_ID, this::updatePluginMap);
1.
watcherData(PLUGIN_DATA_ID, new OnChange() {
@Override
void change(String changeData) {
updatePluginMap();
}
}
2.
watcherData(PLUGIN_DATA_ID, () -> {updatePluginMap()})
总结
Nacos其实流程已经理清楚了,这里面对于lambda语法也巩固了下,对于 接口只有一个方法时候可以使用类::指定方法即可。