在jfinal框架中,有一个Prop的类,该类提供对properties配置文件里获取键值对的功能。
其底层还是用的是java.util.Properties的相关方法,只不过是人家进行了封装而已。牛人都喜欢封装原有的东西。
其构造函数Prop(String fileName,String encoding)
以及Prop(File file,String encoding)
代码都很好理解,如下:
public Prop(String fileName, String encoding) {
InputStream inputStream = null;
try {
inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName); // properties.load(Prop.class.getResourceAsStream(fileName));
if (inputStream == null)
throw new IllegalArgumentException("Properties file not found in classpath: " + fileName);
properties = new Properties();
properties.load(new InputStreamReader(inputStream, encoding));
} catch (IOException e) {
throw new RuntimeException("Error loading properties file.", e);
}
finally {
if (inputStream != null) try {inputStream.close();} catch (IOException e) {e.printStackTrace();}
}
}
其输入参数传递File也可以
public Prop(File file, String encoding) {
if (file == null)
throw new IllegalArgumentException("File can not be null.");
if (file.isFile() == false)
throw new IllegalArgumentException("File not found : " + file.getName());
InputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
properties = new Properties();
properties.load(new InputStreamReader(inputStream, encoding));
} catch (IOException e) {
throw new RuntimeException("Error loading properties file.", e);
}
finally {
if (inputStream != null) try {inputStream.close();} catch (IOException e) {e.printStackTrace();}
}
}
两者的区别就是根据文件名获取InputStream,一种是根据File对象获取InputStream.
其中该类中有一个私有成员变量
private Properties properties = null;
从构造函数中可以看出,调用构造函数之后对该成员变量进行了赋值操作。
所以外层的代码就可以调用期间定义的封装方法了。
如一系列的get方法,加默认值的等等,以及getProperties()返回该成员变量,以及是否包含该key的方法containsKey(String key),其直接调用Properties.containsKey(String key)
有了这个方法之后配合PropKit工具类,就可以发挥其强大的威力了。
使用方式:
PropKit.use("my_config.txt").get("userName")
其中get方法的实现如下:
public static Prop getProp() {
if (prop == null)
throw new IllegalStateException("Load propties file by invoking PropKit.use(String fileName) method first.");
return prop;
}
public static String get(String key) {
return getProp().get(key);
}
告诉我们需要先调用use方法,其他一系列的方法类似。
PropKit采用单例的模型,其构造函数私有,并内部静态成员变量Prop prop,以及Map<String,Prop> ,采用恶汉式,先取再说,如果没有再初始化。
private static Prop prop = null;
private static final Map<String, Prop> map = new ConcurrentHashMap<String, Prop>();
private PropKit() {}
public static Prop use(String fileName, String encoding) {
Prop result = map.get(fileName);
if (result == null) {
result = new Prop(fileName, encoding);
map.put(fileName, result);
if (PropKit.prop == null)
PropKit.prop = result;
}
return result;
}
为了维护该Map,提供了如下两个方法。
public static Prop useless(String fileName) {
Prop previous = map.remove(fileName);
if (PropKit.prop == previous)
PropKit.prop = null;
return previous;
}
public static void clear() {
prop = null;
map.clear();
}