简单把源码过了一遍,总结使用@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运行时数据采用内存实例中静态存储,监听到变化就下载 + 刷新 + 执行回调