每日一句
任何傻瓜都能写出计算机可以理解的代码。好的程序员能写出人能读懂的代码
前面我们把CommonsConfiguration 1.x版本的主要功能算了过了一遍。如果有时间充裕的同学其实可以研究一下2.x版本的内容。我们这里其实主要是为了说Archaius所以就不在讲2.x版本了。
Archaius前面说到 是Netflix公司开发的一套强大的配置管理库。是其他的Netflix组件的基础。我们之所以出了这一个专栏 也是因为大部分的Netflix组件都依赖了Archaius配置管理库。
依赖包
引用 archaius POM
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-core</artifactId>
<version>0.7.6</version>
</dependency>
可以看到它依赖了Commons-Configuration 还有jackson的几个包 毕竟配置有时候需要序列化。
一个demo
还是和之前一样从一个demo开始 简单的了解怎么来使用。
@Test
public void test1(){
AbstractConfiguration configInstance = ConfigurationManager.getConfigInstance();
System.out.println(configInstance.getProperty("con1"));
}
- 默认情况下 它会加载classpath下面的config.properties文件。
- 我们可以看到其实获取的实例还是commons-configuration的Configuration
- 我们并没有new一个实例 而是通过配置管理器(ConfigurationManager)获取一个实例。
ConfigurationManager.getConfigInstance()
从上例中看到 配置管理器获取了一个实例 它就拥有了classpath下的config.properties的属性。我们跟进getConfigInstance方法中去。
public static AbstractConfiguration getConfigInstance() {
if (instance == null) {
synchronized (ConfigurationManager.class) {
if (instance == null) {
instance = getConfigInstance(Boolean.getBoolean(DynamicPropertyFactory.DISABLE_DEFAULT_CONFIG));
}
}
}
return instance;
}
这个很熟悉 是一个单例模式的常规写法 也就是说 我们获取到的Configuration是一个单利对象,不管我们调多少次getConfigInstance获取的都是同一个对象。
Boolean.getBoolean(key) 该方法是从系统变量中获取一个布尔类型的值。所以我们可以System.setProperty(DynamicPropertyFactory.DISABLE_DEFAULT_CONFIG , “true”);这样就获取不到默认的配置实例了。我们继续跟进getConfigInstance()方法:
private static AbstractConfiguration getConfigInstance(boolean defaultConfigDisabled) {
//我们上面的结论可以在这里证实 如果获取的defaultConfigDisabled是一个true那么久不会createDefaultConfigInstance
if (instance == null && !defaultConfigDisabled) {
instance = createDefaultConfigInstance();
registerConfigBean();
}
return instance;
}
继续跟进createDefaultConfigInstance()方法:
private static AbstractConfiguration createDefaultConfigInstance() {
/**这里实例化了一个ConcurrentCompositeConfiguration 但好像也是Configuration的子类
- 是组合模式的一个Configuration和我们之前说的CompositeConfiguration很像 但是多了一个
- Concurrent 所以推测出它应该是线程安全的
*/
ConcurrentCompositeConfiguration config = new ConcurrentCompositeConfiguration();
try {
/**这里又来了一个 DynamicURLConfiguration 但是也应该是一个Configuration的子类
*从名字看好想和动态属性有关系
*/
DynamicURLConfiguration defaultURLConfig = new DynamicURLConfiguration();
//因为config是组合配置 所以可以吧defaultURLConfig加入进去
config.addConfiguration(defaultURLConfig, URL_CONFIG_NAME);
} catch (Throwable e) {
logger.warn("Failed to create default dynamic configuration", e);
}
//判断是否禁用系统配置
if (!Boolean.getBoolean(DISABLE_DEFAULT_SYS_CONFIG)) {
//获取系统配置 SystemConfiguration这个就很熟悉了 在前几节里面讲到过
SystemConfiguration sysConfig = new SystemConfiguration();
//将系统配置加到组合配置里面去
config.addConfiguration(sysConfig, SYS_CONFIG_NAME);
}
//是否禁用系统环境变量
if (!Boolean.getBoolean(DISABLE_DEFAULT_ENV_CONFIG)) {
//这个也是很熟悉 是原生的commons-Configuration里面的类
EnvironmentConfiguration envConfig = new EnvironmentConfiguration();
//同样加载到组合配置里面去
config.addConfiguration(envConfig, ENV_CONFIG_NAME);
}
ConcurrentCompositeConfiguration appOverrideConfig = new ConcurrentCompositeConfiguration();
//再向组合配置中加一个组合配置
config.addConfiguration(appOverrideConfig, APPLICATION_PROPERTIES);
config.setContainerConfigurationIndex(config.getIndexOfConfiguration(appOverrideConfig));
//返回组合配置
return config;
}
我们得到以下的结论:
- 通过配置管理器获取到的一个配置是一个ConcurrentCompositeConfiguration组合配置
- 显示的向组合配置里面加了 一个DynamicURLConfiguration一个SystemConfiguration和一个EnvironmentConfiguration。
- 从添加的配置我们可以猜出来DynamicURLConfiguration这个配置应该就是加载了config.properties
- configList是有顺序的 所有index越小的优先级会越高 因为先找到先返回。和spring的Environment配置实现是一个道理。
再看一下运行完 createDefaultConfigInstance()方法里面的配置情况。
DynamicUrlConfiguration、SystemConfiguration、EnvironmentConfiguration我们大致都能猜出来各自的功能。但是后两个到目前为止还不是太确定。我们放在下一篇介绍。
到这里我们其实把获取一个Configuration的流程过一遍。有一些我们比较陌生的类我们后面的文章会介绍。