简体   繁体   English

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

[英]How to avoid reading property file multiple times

We have some data in properties file. 我们在属性文件中有一些数据。 This data is used across many classes. 这些数据用于许多类。 So, we create a Properties class object in each and every class and then read data using getProperty() method. 因此,我们在每个类中创建一个Properties类对象,然后使用getProperty()方法读取数据。 This is leading to duplication of code. 这导致代码重复。

Can someone please suggest some best practices to avoid this? 有人可以建议一些最佳做法来避免这种情况吗?

One thing that came to my mind is: 我想到的一件事是:
Create a class 创建一个类
Have a public variable for each property in property file in this class 为此类的属性文件中的每个属性设置一个公共变量
Have a method that assigns values to each and every property 有一个方法可以为每个属性分配值
In the class where property values are required, create an object for this class and access the public variables 在需要属性值的类中,为此类创建一个对象并访问公共变量

But, things i don't like with this approach are public variables and if at all a new property is added to the property file, i need to add code to read that property in the class. 但是,我不喜欢这种方法的是公共变量,如果在属性文件中添加了新属性,我需要添加代码来读取类中的该属性。

Any help is appreciated. 任何帮助表示赞赏。

Thank you! 谢谢!

You can create a Singleton class, that loads the properties the first time it gets invoked.. and a public method that retrieves the property value, for a given property key.. 您可以创建一个Singleton类,它在第一次调用时加载属性..以及一个检索给定属性键的属性值的公共方法。

This is assuming you're using a standart Properties file... But you can extrapolate this to any key-value pair, changing Properties type to a Map or something else. 这假设您正在使用标准属性文件...但您可以将其推断为任何键值对,将属性类型更改为Map或其他内容。

Something like 就像是

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

Then you can invoke this as needed.. from any code.. like this. 然后你可以根据需要调用它..从任何代码..像这样。

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

Hope this helps 希望这可以帮助

for me static inner class is the best possible way to do it. 对我来说静态内部类是最好的方法。 It will do it with lazily, as class loading is synchronized so thread safe, plus performant also. 它会懒惰地执行它,因为类加载是同步的,所以线程安全,还有性能。 So with this we are achieving three things: 因此,我们实现了三件事:

  1. good performance because with synchronizing the liveliness will suffer, but here we are using static inner class. 良好的表现,因为同步活力将受到影响,但在这里我们使用静态内部类。
  2. thread safety because when inner class will be loaded than only map will be initialized as the class loading is thread safe hence all total thread safe. 线程安全,因为当内部类将被加载时,只有map将被初始化,因为类加载是线程安全的,因此所有总线程安全。
  3. Inner class will be loaded when we will call Singleton.initialize().get(key) so the map gets initialized lazily. 当我们调用Singleton.initialize().get(key)时,将加载内部类,以便懒惰地初始化地图。

Below is the code... 以下是代码......

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

One out of the box option is to use system properties . 一个开箱即用的选项是使用系统属性 You can add your own system properties to your execution environment. 您可以将自己的系统属性添加到执行环境中。

You can do this with a dedicated class having a static Properties object. 您可以使用具有静态Properties对象的专用类来完成此操作。 See here for an example. 请看这里的例子。

I could be misunderstanding your data flow here, but this is what seems "normal" to me: 我可能会误解你的数据流,但这对我来说似乎是“正常的”:

  • Create a readPropFile method. 创建一个readPropFile方法。
    • This should read a file and appropriately parse the properties it finds. 这应该读取一个文件并适当地解析它找到的属性。
    • These properties can be stored in a Map<String, Object> , hashed by property name. 这些属性可以存储在Map<String, Object> ,并按属性名称进行哈希处理。
  • Read property file once (presumably when the application starts, or whenever it's appropriate to load properties) --> Properties object (say, props ). 读取属性文件一次(可能是在应用程序启动时,或者只要适合加载属性) - > Properties对象(比如说, props )。
  • Pass props around to anything that needs access to those properties. props传递给需要访问这些属性的任何东西。
    • Or if you don't want to pass it around explicitly, use a static accessor as illustrated here . 或者,如果您不想显式传递它,请使用此处所示的静态访问器。
  • Access properties using props.get("PROPERTY_NAME") (which just looks up that property in the internal Map ). 使用props.get("PROPERTY_NAME")访问属性(只在内部Map查找该属性)。
    • If you don't want to use String lookups, you can keep an enum of valid property names somewhere, and do storage/lookups using that, but then you have to update that enum every time you add a new property to the file. 如果您不想使用字符串查找,可以在某处保留有效属性名称的枚举,并使用它进行存储/查找,但是每次向文件添加新属性时都必须更新该枚举。

I've had success using an Enum, and in the constructor using the name() method to read a property of the same name. 我已成功使用Enum,并在构造函数中使用name()方法读取同名属性。 Be sure to handle exceptions in a reasonable way or else the whole class will fail to load and you won't get a helpful error message. 确保以合理的方式处理异常,否则整个类将无法加载,您将不会收到有用的错误消息。

Benefits of this approach are that each enum value automatically corresponds to a property without having to write individual mapping code for each property. 这种方法的好处是每个枚举值自动对应一个属性,而不必为每个属性编写单独的映射代码。 You do of course need an enum value for each property (that's unavoidable if you want DRY prop references), but you avoid repetitive per-property initialization code using unchecked Strings. 你当然需要每个属性的枚举值(如果你想要DRY prop引用那是不可避免的),但你要避免使用未经检查的字符串重复的每个属性初始化代码。

Drawbacks are that enums don't allow generic types, so if you wanted certain properties to return Integer and others to return String, then you might be better served with a classic singleton class design. 缺点是枚举不允许泛型类型,因此如果您希望某些属性返回Integer而其他属性返回String,那么使用经典的单例类设计可能会更好。

If you want to go crazy with this you could also write a script to generate your Enum or singleton java source code from the properties file, to keep your code extra DRY. 如果你想对此发疯,你也可以编写一个脚本来从属性文件中生成你的Enum或singleton java源代码,以使你的代码更加干燥。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM