2009年8月11日 星期二

Configuration

Java 中有個好用的物件, Properties, 可以將常常會修改的資料存在這裡 (file) , 通常會以 .properties 結尾, 也可以用 xml 檔案.

每次要使用時, 必須寫一堆 code :

package hank.jakarta.common.configuration;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ConfigurationTest {

public static final Log log = LogFactory.getLog(ConfigurationTest.class);
public static final String propName = "mmmm.properties";

private String name;
private String working;

private Properties prop;

private ConfigurationTest() {
// do something
try {
initProp();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}

private static class SingletonHolder {
private static final ConfigurationTest instance = new ConfigurationTest();
}

public static ConfigurationTest getInstance() {
return SingletonHolder.instance;
}

private void initProp() throws IOException {
if (prop == null) {
prop = new Properties();
String realPath = getClass().getClassLoader().getResource(propName)
.getPath();
File f = new File(realPath);
if (!f.isFile()) {
throw new FileNotFoundException("path not found!! : " + realPath);
} else {
prop.load(new FileInputStream(f));
// load properties ......
setName(prop.getProperty("name"));
setWorking(prop.getProperty("working"));
}
}
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getWorking() {
return working;
}

public void setWorking(String working) {
this.working = working;
}

public static void main(String[] args) {
// test
ConfigurationTest config = ConfigurationTest.getInstance();
System.out.println(config.getName());
System.out.println(config.getWorking());
}
}



來看看紅色的地方, 每當使用時 (假設檔案是放在 classes 裡), 必須自己經過一些處理後, 再把變數都 setter 好, 才能使用. 這種是一般最常件的方法.

昨天在 surfing jakarta website 時, 看到一個好用的 tool - Jakarta commons-configuration
把一堆 code 都封裝了起來, 我們要用使就變得特別方便, 也可以設定他動態 reload 的方式.


package hank.jakarta.common.configuration;


import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ConfigurationTest1 {

public static final Log log = LogFactory.getLog(ConfigurationTest1.class);
public static final String propName = "mmmm.properties";

private String name;
private String working;

private PropertiesConfiguration prop;

private ConfigurationTest1() {
// do something
try {
initProp();
} catch (ConfigurationException e) {
log.error(e.getMessage(), e);
}
}

private static class SingletonHolder {
private static final ConfigurationTest1 instance = new ConfigurationTest1();
}

public static ConfigurationTest1 getInstance() {
return SingletonHolder.instance;
}

private void initProp() throws ConfigurationException {
if (prop == null) {
prop = new PropertiesConfiguration(propName);
}
// load properties ......
// String
setName(prop.getString("name"));
setWorking(prop.getString("working"));
// 如果是 double, 可以這樣寫, 就會幫你轉好了.
// prop.getDouble("double");

// 其它像 integer, ...都是.

// 那如何動態 reload 呢?, 其實很簡單
prop.setReloadingStrategy(new FileChangedReloadingStrategy());

// FileChangedReloadingStrategy <-- 這個是指, 當你修改了 attribute 時, 下一次去存取時, 會先去檢查最後修改日期, 來判斷他是否有修改, 如果有, 就 reaload.

}


public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getWorking() {
return working;
}

public void setWorking(String working) {
this.working = working;
}

public static void main(String[] args) {
ConfigurationTest1 config = ConfigurationTest1.getInstance();
System.out.println(config.getName());
System.out.println(config.getWorking());
}
}



今天先分享到這. 打球囉.

1 意見:

Todd 提到...

媽啊~真是棒
又有收獲了~肛蝦啊