[关闭]
@pastqing 2015-01-20T17:10:14.000000Z 字数 2507 阅读 5565

使用java枚举实现单例模式读取配置文件

java


一个枚举Enum常量代表了一个实例,enum类型只能有这些常量实例。这样的标准保证enum常量不能被克隆,也不会因为反序列化产生不同的实例,想通过反射机制得到一个enum类型的实例也是不行的。因此可以用枚举Enum来实现单例模式。下面看一个例子:

  1. public enum ConfigReader {
  2. SDUST;
  3. private volatile Properties configuration = new Properties();
  4. public void init() {
  5. InputStream is = this.getClass().getResourceAsStream("db-configuration.xml");
  6. if( is != null ) {
  7. this.configuration.clear();
  8. try {
  9. this.configuration.loadFromXML(is);
  10. //this.configuration.load(is);
  11. } catch (InvalidPropertiesFormatException e) {
  12. System.out.println("Properties 格式不对");
  13. e.printStackTrace();
  14. } catch (IOException e) {
  15. e.printStackTrace();
  16. }finally { //无论异常是否发生, 都关闭
  17. try {
  18. is.close();
  19. } catch (IOException e) {
  20. // TODO Auto-generated catch block
  21. e.printStackTrace();
  22. }
  23. }
  24. }
  25. }
  26. public String getConfigurationValue(String key) {
  27. return this.configuration.getProperty(key);
  28. }

这里我只定义了一个枚举常量SDUST, 以及两个方法init与getValue方法,用于将配置文件放到Properties对象中。那么从哪里获得这个Properties呢? 为此我又写了一个常量类,来存储配置文件信息:

  1. /**
  2. * 常量类
  3. * @author su
  4. */
  5. public final class Contants {
  6. private Contants() {
  7. }
  8. /**
  9. * 配置文件常量
  10. */
  11. public final static class Configuration {
  12. private Configuration() {
  13. }
  14. public static final Map<String, Configurations> configMap = new HashMap<String, Configurations>();
  15. private static Configurations sql, mysql;
  16. public static final void init() {
  17. /**
  18. * 构造
  19. */
  20. sql = new Configurations();
  21. mysql = new Configurations();
  22. //mysql
  23. mysql.setDb_driver(ConfigReader.SDUST.getConfigurationValue("MYSQL_DRIVER"));
  24. mysql.setDb_path(ConfigReader.SDUST.getConfigurationValue("MYSQL_URL"));
  25. mysql.setDb_name(ConfigReader.SDUST.getConfigurationValue("MYSQL_USERNAME"));
  26. mysql.setDb_pass(ConfigReader.SDUST.getConfigurationValue("MYSQL_PASSWORD"));
  27. //sqlserver
  28. sql.setDb_driver(ConfigReader.SDUST.getConfigurationValue("SQL_DRIVER"));
  29. sql.setDb_path(ConfigReader.SDUST.getConfigurationValue("SQL_URL"));
  30. sql.setDb_name(ConfigReader.SDUST.getConfigurationValue("SQL_USERNAME"));
  31. sql.setDb_pass(ConfigReader.SDUST.getConfigurationValue("SQL_PASSWORD"));
  32. //
  33. System.out.println("put map");
  34. configMap.put("sql", sql);
  35. configMap.put("mysql", mysql);
  36. }
  37. }
  38. }

常量类中的配置文件子类中, 我用一个map作为存储单元。他的key是表示哪种数据库,例如sqlserver, mysql, mongDB等。value是数据库配置文件的一个bean类, 里面包含属性的get与set方法。这样在写发起数据库连接等jdbc操作时, 就可以灵活的选择了。我的写法如下:

  1. public Connection getConnection(String type) {
  2. //根据传入的类型做判断, 来选择调用常量类中configMap里面的value
  3. Connection DBConn = null;
  4. Contants.Configuration.init();
  5. //使用type别忘记做各种判断
  6. Configurations config = configMap.get(type);
  7. //下面就是连接数据库的各种操作了, 此处省略
  8. ...
  9. ...
  10. }

下面说一下何时调用我们写的用Enum单例模式来读入文件的方法, 即上面ConfigReader类中的init方法。 我们的需求是服务器启动后就加载配置文件到内存中, 服务器启动时会有很多方法伴随启动调用(如各种容器的init方法), 这里我选用了过滤器的init方法。 定义一个过滤器, 在其init方法中调用我们枚举常量的方法, 即ConfigReader.SDUST.init();

感觉利用java枚举的特性写单例模式还是比较新颖的, 也比较安全。故记录之。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注