目標(biāo)
-
soul-bootstrap 端 Nacos 啟動流程
- pom 依賴配置
- yml 配置
- 初始化分析
Nacos 數(shù)據(jù)如何接收消息發(fā)布事件
拿到數(shù)據(jù)之后如何處理
Java Interface將接口作為參數(shù)傳遞
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
- 創(chuàng)建ConfigService
我們知道Nacos三元素確定唯一,所以這里面ConfigService就是制定三元素和一些地址信息
yml配置

初始化分析
下面分析下Nacos初始化流程,通過調(diào)用 watcherData 方法,使用Nacos提供的 Listener 來注冊當(dāng)Nacos發(fā)布配置時候,可以監(jiān)聽到事件。這里面巧妙的設(shè)計使用了interface 作為參數(shù)將不同種配置發(fā)生變化分別去執(zhí)行不同的處理Function。
科普下:
接口是Java編程語言中的一種抽象類型,是抽象方法的集合,通常以interface來聲明,所以接口不是類,盡管寫法相似。
一個類通過實現(xiàn)接口的方式來繼承接口的方法。
除非實現(xiàn)接口的類是抽象,否則該類要定義接口中所有方法。
最后一句,也就解釋了,soul中為什么很多interface,都會緊跟著一個abstract,只是為了實現(xiàn)N個繼承的實際業(yè)務(wù)類的公共方法。
oc.change()
定義好listener之后下面進行綁定 dataId 與 listener。
LISTENERS 進行存儲dataId 與對應(yīng)的事件監(jiān)聽器
Nacos 數(shù)據(jù)如何接收消息發(fā)布事件
初始化時候?qū)⒉煌膁ataId綁定到不同的updateXXMap,等待admin數(shù)據(jù)發(fā)生變動,自動觸發(fā)listener
拿到數(shù)據(jù)之后如何處理
這里我們拿plugin解析。拿到數(shù)據(jù)變化之后,先序列化成List,然后循環(huán)一次的先發(fā)送批量解綁事件給關(guān)心此數(shù)據(jù)的Plugin,然后在綁定,從這里我們可以看出,這里面采用的是批量操作。
Java Interface 將接口作為參數(shù)傳遞
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);
}
}
- 看下這兩個類,一個是接口,他們的關(guān)系是什么?
class B 作為程序入口類,實現(xiàn)了interface TestInterface,并定義了接口中的systemStr
主方法main()中實例化class A,并將自身class B的實例化對象傳入。
在class A中定義一個接口TestInterface類型的成員變量 test,一個具體的方法doSth()
其構(gòu)造方法接受主方法中傳來的數(shù)據(jù)并初始化成員變量test
doSth方法執(zhí)行方法systemStr()
- class A的構(gòu)造定義了TestInterface,為什么傳入ClassB實例也可以
這里面涉及到Java 自動轉(zhuǎn)型,TestInterface test 由編譯器自動向下轉(zhuǎn)型為classB,實際執(zhí)行的方法是由classB 繼承自testInterface并定義的systemcStr()方法。雖然接受的類型為TestInterface,但是接口不能實例化,所以我們要定一個類來實現(xiàn)接口。并將這個類型傳遞過去。
所以我們可以定義classA的構(gòu)造方法接受類型為classB
匿名內(nèi)部類的lambda語法
- 定義
watcherData(final String dataId, final OnChange oc);
interface OnChange(){
void change();
}
- 調(diào)用
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()})
總結(jié)
Nacos其實流程已經(jīng)理清楚了,這里面對于lambda語法也鞏固了下,對于 接口只有一個方法時候可以使用類::指定方法即可。