【问题标题】:How to avoid reading property file multiple times如何避免多次读取属性文件
【发布时间】:2013-08-29 17:23:04
【问题描述】:

我们在属性文件中有一些数据。该数据用于许多类。因此,我们在每个类中创建一个 Properties 类对象,然后使用 getProperty() 方法读取数据。这会导致代码重复。

有人可以建议一些最佳做法来避免这种情况吗?

我想到的一件事是:
创建一个类
为此类中的属性文件中的每个属性都有一个公共变量
有一个为每个属性分配值的方法
在需要属性值的类中,为该类创建一个对象并访问公共变量

但是,我不喜欢这种方法的东西是公共变量,如果在属性文件中添加了一个新属性,我需要添加代码来读取类中的该属性。

感谢任何帮助。

谢谢!

【问题讨论】:

标签: java


【解决方案1】:

您可以创建一个 Singleton 类,它在第一次被调用时加载属性.. 以及一个为给定属性键检索属性值的公共方法..

这是假设您使用的是标准属性文件...但是您可以将其推断为任何键值对,将属性类型更改为 Map 或其他内容。

类似

public class PropertyHandler{

   private static PropertyHandler instance = null;

   private Properties props = null;

   private PropertyHandler(){
         // Here you could read the file into props object
         this.props = ..... 
   }

   public static synchronized PropertyHandler getInstance(){
       if (instance == null)
           instance = new PropertyHandler();
       return instance;
   }

   public String getValue(String propKey){
       return this.props.getProperty(propKey);
   }
}

然后你可以根据需要调用它......从任何代码......像这样。

String myValue = PropertyHandler.getInstance().getValue(propKey);

希望对你有帮助

【讨论】:

  • 如果 PropertyHandler 将被多个线程使用,那么 getInstance 应该被同步。
  • 你说得对......已修复......(我是即时写的......我忘了......)
  • 是的,这有帮助。非常感谢。另外,感谢所有回复的人。
  • 如果有帮助,请用绿色的“勾号”将答案标记为正确。谢谢!
【解决方案2】:

对我来说,静态内部类是最好的方法。它会懒惰地做到这一点,因为类加载是同步的,所以线程安全,而且性能也很好。因此,我们正在实现三件事:

  1. 良好的性能,因为同步会影响活力,但这里我们使用的是静态内部类。
  2. 线程安全,因为当加载内部类时,只会初始化映射,因为类加载是线程安全的,因此所有线程都是安全的。
  3. 当我们调用Singleton.initialize().get(key) 时会加载内部类,因此地图会延迟初始化。

下面是代码...

public class SingletonFactory 
{   
    private static class Singleton
    {
        private static final Map<String, String> map = new HashMap<String, String>();
        static
        {
            try
            {
                //here we can read properties files
                map.put("KEY", "VALUE");
            }
            catch(Exception e)
            {
                //we can do the exception handling
                System.out.println(e);
            }
        }
        private static Map<String, String> initialize()
        {   
            return map;
        }
    }

    public static String getValue(String key)
    {
        return Singleton.initialize().get(key);
    }
}

【讨论】:

    【解决方案3】:

    一个开箱即用的选项是使用system properties。您可以将自己的系统属性添加到执行环境中。

    【讨论】:

      【解决方案4】:

      您可以使用具有静态 Properties 对象的专用类来做到这一点。示例见here

      【讨论】:

        【解决方案5】:

        我可能在这里误解了您的数据流,但这对我来说似乎是“正常的”:

        • 创建一个readPropFile 方法。
          • 这应该读取一个文件并适当地解析它找到的属性。
          • 这些属性可以存储在Map&lt;String, Object&gt; 中,按属性名称散列。
        • 读取一次属性文件(大概是在应用程序启动时,或者在适合加载属性时)--> Properties 对象(例如,props)。
        • props 传递给需要访问这些属性的任何对象。
          • 或者,如果您不想明确地传递它,请使用静态访问器,如图所示 here
        • 使用props.get("PROPERTY_NAME") 访问属性(它只是在内部Map 中查找该属性)。
          • 如果您不想使用字符串查找,您可以在某处保留一个有效属性名称的枚举,并使用它进行存储/查找,但是您必须在每次向文件。

        【讨论】:

        • 谢谢,这也很有用
        【解决方案6】:

        我已经成功使用了枚举,并在构造函数中使用 name() 方法读取了同名的属性。请务必以合理的方式处理异常,否则整个类将无法加载,您将不会收到有用的错误消息。

        这种方法的好处是每个枚举值自动对应一个属性,而无需为每个属性编写单独的映射代码。当然,每个属性都需要一个枚举值(如果你想要 DRY 属性引用,这是不可避免的),但是你可以避免使用未经检查的字符串重复每个属性的初始化代码。

        缺点是枚举不允许泛型类型,因此如果您希望某些属性返回 Integer 而其他属性返回 String,那么使用经典的单例类设计可能会更好。

        如果您想对此感到疯狂,您还可以编写一个脚本来从属性文件中生成您的 Enum 或单例 Java 源代码,以保持您的代码额外干燥。

        【讨论】:

          猜你喜欢
          • 2014-08-22
          • 2011-06-06
          • 1970-01-01
          • 2023-03-08
          • 1970-01-01
          • 2019-07-05
          • 2016-11-22
          • 2013-08-12
          • 2019-10-06
          相关资源
          最近更新 更多