我有一系列不同类型的应用程序属性。
这些类型可能包括布尔值、日期、时间戳或字符串。
我需要能够为管理员用户提供更改这些属性的功能,并使系统记住/将它们持久化到文件中。
我正在寻找一种最佳实践方法来存储这些应用程序属性,并能够在更改时持久化它们并在启动时加载它们。
我有一系列不同类型的应用程序属性。
这些类型可能包括布尔值、日期、时间戳或字符串。
我需要能够为管理员用户提供更改这些属性的功能,并使系统记住/将它们持久化到文件中。
我正在寻找一种最佳实践方法来存储这些应用程序属性,并能够在更改时持久化它们并在启动时加载它们。
来自未来的信息:链接已经失效了。
Java有一个专门为此目的构建的工具——Properties。 以下是一篇非常好的相关文章:
https://docs.oracle.com/javase/tutorial/essential/environment/properties.html
如果您有存储和读取不同类型属性的需求,例如布尔值、整数等,我认为java.util.prefs
API是一个不错的选择。它允许您存储和读取各种数据类型。
这里是API文档。
java.util.Properties
是最简单的方法。可以从属性文件 (一个包含 name=value
格式属性的文件) 或简单的 XML 文件创建 Properties
对象。您可以在内存中修改对象,然后将其写回属性或 XML 文件。
如果需要更大的灵活性来构建属性,可以考虑设计自己的XML配置文件,尽管读写可能需要更多的工作。但是您可以使用像 JAXB、XStream 等序列化/反序列化 API,使任务更加容易。
这些文件也可以很容易地手动修改。
我使用这段代码,对我来说效果非常好(只是部分代码,从记忆中编写..): (这与Java的Properties类一起使用,但它使添加属性和保持属性文件模板同步更容易。)
to use:
Date date = Conf.value(Prop.SOME_DATE,Date.class);
并且
enum Prop {
SOME_DATE(Date.class, "2009-10-28", "Some date"){
Object parse(String value){
return new Date(value);
}};
private final Class<?> type;
private final String description;
private final Object default;
Properties(Class<?> type, String defaultValue, String desc){
this.type = type;
this.description = desc;
this.default = this.parse(defaultValue);
}
abstract Object parse(String value);
}
并且
class Conf {
private static final String PROP_FILE_NAME = "some.properties";
private volatile Map<Prop,Object> store;
public void load(){
//Read from property file and use default if not given.
//I code it in a way that it will not permit null as value, so
//if default is null the user is forced to provide setting.
}
public <T> T value(Prop prop, Class<T> clazz){
return (T)this.store.get(prop);
}
public static void main(String[] args){
//code to autogenerate property file
//Something like:
//#Default : 2009-10-28 Description : Some date. Type:Date
//#SOME_DATE=2009-10-28
}
}
class 参数让方法有点啰嗦,但有时如果只能让 Java 推断类型会很烦人,就像这样:
CountDownLatch latch = Conf.value(Prop.SOME_INTEGER);
//Compilation error! Since it expects int and won't unbox.
CountDownLatch latch = Conf.value(Prop.SOME_ITEGER,Integer.class);
//Verbose, but works everytime. Of course you could get a
//ClassCastException, but you should notice that early
//in the development...
你可以将它们存储在数据库中,但由于属性的数据类型不同,你必须以字符串表示形式存储它们。你可以使用另一列来指定数据类型。
这种应用程序参数化的形式是我在工作中成功使用过的。这是一个大致的想法,希望你能用这个方法找到解决方案。
尽管您应该使用首选项 API 或属性,但这里有一个可能也有效的技巧:
创建一个 HashMap<String,Object>
并使用 XMLEncoder/XMLDecoder 进行保存/加载。大多数标准 Java 类可以通过此方式序列化为 Java Bean。您可以创建一个简单的包装类来获取各种属性、处理默认值等。这样,您还可以存储嵌套集合,有时非常方便。它真的很容易实现。