如何避免多次读取属性文件

时间:2013-08-29 17:23:05

标签: java

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

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

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

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

感谢任何帮助。

谢谢!

6 个答案:

答案 0 :(得分:20)

您可以创建一个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);

希望这有帮助

答案 1 :(得分:2)

对我来说静态内部类是最好的方法。它会懒惰地执行它,因为类加载是同步的,所以线程安全,还有性能。因此,我们实现了三件事:

  1. 良好的表现,因为同步活力会受到影响,但这里我们正在使用静态的内部阶级。
  2. 线程安全,因为当加载内部类时,只有map才会被初始化,因为类加载是线程安全的,因此所有的线程都是安全的。
  3. 我们将调用Singleton.initialize().get(key)时会加载内部类,以便懒惰地初始化地图。
  4. 以下是代码......

    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);
        }
    }
    

答案 2 :(得分:0)

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

答案 3 :(得分:0)

您可以使用具有静态Properties对象的专用类来执行此操作。有关示例,请参阅here

答案 4 :(得分:0)

我可能会误解你的数据流,但这对我来说似乎是“正常的”:

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

答案 5 :(得分:0)

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

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

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

如果你想对此发疯,你也可以编写一个脚本来从属性文件中生成你的Enum或singleton java源代码,以保持你的代码更加干净。