Configuration类有三个构造函数:
public Configuration() {
this(true);
}
public Configuration(boolean loadDefaults) {
this.loadDefaults = loadDefaults;
if (LOG.isDebugEnabled()) {
LOG.debug(StringUtils.stringifyException(new IOException("config()")));
}
synchronized(Configuration.class) {
REGISTRY.put(this, null);
}
this.storeResource = false;
}
@SuppressWarnings("unchecked")
public Configuration(Configuration other) {
if (LOG.isDebugEnabled()) {
LOG.debug(StringUtils.stringifyException
(new IOException("config(config)")));
}
this.resources = (ArrayList)other.resources.clone();
synchronized(other) {
if (other.properties != null) {
this.properties = (Properties)other.properties.clone();
}
if (other.overlay!=null) {
this.overlay = (Properties)other.overlay.clone();
}
}
this.finalParameters = new HashSet<String>(other.finalParameters);
synchronized(Configuration.class) {
REGISTRY.put(this, null);
}
}
第一个是默认的无参构造器,
第二个是指定loadDefaults值的构造器,然后synchronized修饰的代码块表示同步代码块,当其他线程试图访问该对象时将会被阻塞,这里是将生成的Configuration对象添加到REGISTRY【这个对象在上一节已经讲过】中。
第三个构造函数传入参数是一个Configuration对象,将传入的Configuration对象的properties和overlay里的内容全部clone()到新生成的Configuration对象中,然后添加到REGISTRY中。
Configuration类还包含一个private类型的构造函数。如下:
private Configuration(Configuration other, boolean storeResource) {
this(other);
this.loadDefaults = other.loadDefaults;
this.storeResource = storeResource;
if (storeResource) {
updatingResource = new HashMap<String, String>();
}
}
在Configuration类中有两个存放配置文件的ArrayList,一个是
private ArrayList<Object> resources = new ArrayList<Object>();
另一个是
private static final CopyOnWriteArrayList<String> defaultResources =
new CopyOnWriteArrayList<String>();
defaultResources 在上一节已经说过,这里来看看resources主要是干什么的。
resources对象最重要的使用是在方法addResourceObject()中,源码如下:
private synchronized void addResourceObject(Object resource) {
resources.add(resource);// add to resources
reloadConfiguration();
}
而调用这个方法的地方有:
public void addResource(String name) {
addResourceObject(name);
}
public void addResource(URL url) {
addResourceObject(url);
}
public void addResource(Path file) {
addResourceObject(file);
}
public void addResource(InputStream in) {
addResourceObject(in);
}
所以说在调用addResource方法的时候,填入的参数无论是Path,InputStream,String,URL,都会被添加到resources中,也就是说,默认配置文件是通过addDefaultResource(String name)加载的,也就存放在defaultResources这个容器中的,而外部添加的配置文件是放在resources容器中的。resources是一个可包含Object类型的ArrayList。
addResourceObject最后还执行了reloadConfiguration()方法,源码如下:
public synchronized void reloadConfiguration() {
properties = null;// trigger reload
finalParameters.clear();// clear site-limits
}
reloadConfiguration()中的语句是将内存中存在的name-value都清空,之后又得重新将配置文件载入内存。
从上可以看到,无论是调用addResourceObject(),还是addResource(),最终都会执行reloadConfiguration()方法,清空内存的name-value
而addDefaultResource()中
if(conf.loadDefaults) {
conf.reloadConfiguration();
}
通过loadDefaults来判断是否执行reloadConfiguration()方法,loadDefaults默认为true,也就是默认会执行reloadConfiguration()方法,清空内存中存在的name-value值,在下一次调用时重新加载到内存中。