簡單把源碼過了一遍,總結使用@DisconfFile和@DisconfFileItem註解相結合情況下的Disconf-Client的執行過程、原理
配置類定義如下:
/**
* @author sam
*/
@Service
@Scope("singleton")
@DisconfFile(filename = "uvb76.properties")
public class PropertiesHolder implements IDisconfUpdate {
private String username;
@DisconfFileItem(name = "username", associateField = "username")
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public void reload() throws Exception {
// do something
}
}
第一次掃描:1、加載、導入Disconf配置(運行之前配置的那些東西:比如disconf.properties,zk地址,遠程地址、版本、app、各種自定義配置)
2、掃描applacationContext.xml裏面 <property name="scanPackage" value="”/> 中value指定的包下的基本信息:反射拿取寫了Disconf定義的註解的信息(本例中是@DisconfFile和@DisconfFileItem),放到ScanStaticModel中
ScanStaticModel存儲但不限於:寫了@DisconfFile的類、寫了@DisconfFileItem的get方法、寫了@DisconfUpdateService的類
3、分析ScanStaticModel中數據,分析配置文件類和配置項的對應關係,形成Map<Class<?>, Set<Method>>,校驗每個配置是否有對應的配置文件
4、分析ScanStaticModel中數據,把每個寫了@DisconfFile註解的類,轉換成一個DisconfCenterFile實體(包含配置項信息)
5、把4中每個DisconfCenterFile放入DisconfCenterStore(中央存儲)中的confItemMap中,結構如下:Map<配置文件的名稱, DisconfCenterFile>
6、根據Disconf配置,初始化Fetcher(遠程配置下載器) Watcher(zookeeper監視器)
7、遍歷中央存儲DisconfCenterStore中的confItemMap,對每個DisconfCenterFile做以下幾件事:
- 去Disconf服務端下載每個配置文件,放到指定位置(用戶配置的下載位置,如果是需要放到classpath的,文件複製到classpath下)
- 讀取下載下來的文件內容,把裏面的配置項,注入每個配置文件DisconfCenterFile的Map<String, FileItemValue> keyMaps中,每個配置項對應一個FileItemValue實體
- watcher設置好這個配置文件的監聽,開啓文件內容變化的監聽
至此完成配置文件、配置項、回調函數的對應關係入中央倉庫,完成了監視設置,目前具體配置的值還未注入具體的配置實體,說白了就是配置實例中的配置值還是空的
對應本例中:就是說PropertiesHolder裏的username還是空的。具體的注入在第二次掃描中
第二次掃描:
1、讀取ScanStaticModel,將每個配置的回調函數實例化並寫入倉庫, 填充中央倉庫裏每個配置項的DisconfCommonCallbackModel:disconfConfUpdates,LIST<回調類>
2、遍歷DisconfCenterStore,逐個文件地讀取配置項的值,調用每個具體配置類的set方法(如果set方法是空的則採用field直接set的方式),把配置值,注入配置實體,至此,我們的程序可以從配置類獲取配置值了。對應本例中:就是說PropertiesHolder裏的username已經填充好了,可以被用了
應用運行中監聽到配置變化:
從遠程下載最新配置 --> 更新中央倉庫 --> 更新配置實例(再次調用set方法注入)--> 調用用戶自己實現的IDisconfUpdate : reload()方法,再次設置好監視(zk特性:監視是一次性的)
總結:Disconf-Client說白了就是反射的運用 + zookeeper:反射拿取信息,zookeeper實現變化監聽
web端負責UI,配置操作,配置持久化,變化通知等。
Disconf-Client運行時數據採用內存實例中靜態存儲,監聽到變化就下載 + 刷新 + 執行回調