上一篇文章,介绍了java中四种单例设计模式;其中,可以使用枚举类型方式实现单例设计模式,但是实现的例子比较简单,本文将通过枚举单例,实现如何同时读取xml、properties属性配置文件。在回味枚举单例的使用同时,介绍一些属性配置文件的使用方式。

    1、代码实现

package com.prop.io;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.HashMap;import java.util.Map;import java.util.Properties;/** * 读取Xml、Properties属性配置文件 * 该类设计的仅仅是固定路径的读取属性配置文件,当然可以去设计的更加强大, * 动态的读取不同的属性文件。这里不做设计介绍,仅仅介绍如果利用枚举单例, * 以及如何读取属性配置文件 * @author wangzp * */public enum IoProp {	/**	 * .properties属性配置文件单例	 */	PROP_INSTANCE("/config/jdbc.properties", false){		@Override		public void init(String filePath, boolean isXml) {			try {				prop = new Properties();				prop.load(IoProp.class.getResourceAsStream(filePath));			} catch (IOException e) {				e.printStackTrace();			}					}	},	/**	 * .xml属性配置文件单例	 */	XML_INSTANCE("/config/jdbc.xml", true) {		@Override		public void init(String filePath, boolean isXml) {			try {				prop = new Properties();				prop.load(IoProp.class.getResourceAsStream(filePath));			} catch (IOException e) {				e.printStackTrace();			}		}	};		protected Properties prop;		/**	 * 配置文件相对路径	 */	private String filePath;		/**	 * 是否是xml属性文件类型	 */	private boolean isXml;		private IoProp(String filePath, boolean isXml){		this.filePath = filePath;		init(filePath, isXml);	}		public abstract void init(String filePath, boolean isXml);		/**	 * 获取属性值	 * @param key	 * @return	 */	public String getProp(String key){		return prop.getProperty(key);	}		/**	 * 设置属性值	 * @param key	 * @param value	 * @param isStore 是否将添加的属性值,映射到文件中	 */	public void setProp(String key, String value, boolean isStore){		Map
 props = new HashMap
(); props.put(key, value); this.setProps(props, isStore); } /**  * 批量这是属性值  * @param props 属性值对象  * @param isStore 是否将添加的属性值,映射到文件中  */ public void setProps(Map
 props, boolean isStore) {  prop.putAll(props); try { if (isStore){ String basePath = IoProp.class.getResource("/").getPath(); File file = new File(basePath + File.separator + filePath); if (isXml){ prop.storeToXML(new FileOutputStream(file, true), ""); }else { prop.store(new FileOutputStream(file, true), ""); } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }

    2、相关测试

package com.prop.io.test;import java.util.HashMap;import java.util.Map;import org.junit.Test;import static org.junit.Assert.*;import com.prop.io.IoProp;/** * 测试{@link IoProp} * @author wangzp * */public class IoPropTest {	/**	 * 测试{@link IoProp#setProp(String, String, boolean)}	 */	@Test	public void testSetProp(){		Map
 props = new HashMap
(); props.put("username", "root"); props.put("password", "root"); IoProp.PROP_INSTANCE.setProps(props, true); IoProp.XML_INSTANCE.setProps(props, true); } /**  * 测试{@link IoProp#getProp(String)}  */ @Test public void testGetProp(){ assertEquals(IoProp.PROP_INSTANCE.getProp("username"), "root"); assertEquals(IoProp.XML_INSTANCE.getProp("username"), "root"); }}

    3、总结

    经验:在开发中属性配置文件,几乎是必不可少的元素;开发时总是面临线下环境和线上环境的困扰,你可以通过动态设置属性配置文件,更加友好的管理属性配置文件。这样当你仅仅需要更新属性值的时候,不再需要打包更新了,而是直接通过接口方式实现。

    注:读取配置文件可以使用:类.class.getResrouceAsStream()方法,如果参数不加"/"那么表示当前类路径,如果加"/"表示根路径下。