java 加载属性的最佳策略是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1230246/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the best strategy for loading properties?
提问by Jo?o Silva
I have several classes that need to load some properties files, and I was wondering what are the best practices to accomplish this. I thought of two basic approaches:
我有几个类需要加载一些属性文件,我想知道实现这一点的最佳实践是什么。我想到了两种基本方法:
Hardcode the properties file name in each class, and then use the
Propertiesclass to load from aFileInputStream, which can be problematic if someone decides to change the name of the properties file, as it is hardcoded in the code.public class A { public A() { Properties p = new Properties().load( new FileInputStream("properties/Aconfig.properties")); String value = p.getProperty("key", ""); } }Create a method that, given a class name, loads a properties file that has the same name as the class. Though this approach doesn't require to hardcode the properties file name, it does require that we follow some convention in naming the files, which can cause confusion.
public class A { public A() { Properties p = PropertiesHelper.loadFromClassName(A.class.getName()); // here, we **assume** that there is a A.properties file in the classpath. } }
在每个类中硬编码属性文件名,然后使用
Properties该类从 加载FileInputStream,如果有人决定更改属性文件的名称,这可能会出现问题,因为它在代码中是硬编码的。public class A { public A() { Properties p = new Properties().load( new FileInputStream("properties/Aconfig.properties")); String value = p.getProperty("key", ""); } }创建一个方法,在给定类名的情况下,加载与类同名的属性文件。虽然这种方法不需要对属性文件名进行硬编码,但它确实需要我们在命名文件时遵循一些约定,这可能会导致混淆。
public class A { public A() { Properties p = PropertiesHelper.loadFromClassName(A.class.getName()); // here, we **assume** that there is a A.properties file in the classpath. } }
However, there may be many other more elegant approaches, and that's why I posed these questions: i) What are the best practices for loading properties files in Java?; ii) Do you use any helper class that takes care of the job?; iii) Where (in the code) do you typically load the properties file?
但是,可能还有许多其他更优雅的方法,这就是我提出这些问题的原因:i) 在 Java 中加载属性文件的最佳实践是什么?ii) 您是否使用任何帮助完成工作的类?iii) 您通常在哪里(在代码中)加载属性文件?
Also, is it OK for a class to "auto-load" its properties? Or should I pass the arguments that I need to the constructor ? The problem of passing the arguments, is that there are way too many for some classes (~20, which represent parameters in a statistical model).
另外,类是否可以“自动加载”其属性?或者我应该将我需要的参数传递给构造函数?传递参数的问题是某些类的参数太多(~20,代表统计模型中的参数)。
采纳答案by ChssPly76
The bestpractice would be to use some kind of dependency injectioncontainer - for example Spring Frameworkor Google Guice.
在最好的做法是使用某种依赖注入容器-例如Spring框架或谷歌吉斯。
It solves all kinds of problems - you don't tie your class to particular property file name, you don't have to worry about loading said properties within that class and handle possible exceptions, and you don't have to pass 30 property file names as command line arguments (or system properties).
它解决了各种问题——您不必将您的类绑定到特定的属性文件名,您不必担心在该类中加载所述属性并处理可能的异常,并且您不必传递 30 个属性文件名称作为命令行参数(或系统属性)。
It also helps with many, many other things in addition to property loading :-) - try it, and you'll wonder how you ever lived without.
除了加载属性外,它还有助于许多其他事情:-) - 尝试一下,您会想知道没有它您是如何生活的。
Update:Incidentally, your other questionis also one of those things that Spring would take care of.
更新:顺便说一下,您的另一个问题也是 Spring 会处理的问题之一。
Update #2:I just realized I've already tried to push Springon you :-) At the risk of repeating myself, Spring would really help with abstraction here. Depending on what you store in your property files you may not need them at all (if they deal with configuration) or you will get a very nice API for dealing with them (if they're resource bundles or something similar) .
更新 #2:我刚刚意识到我已经尝试将 Spring 推给你 :-) 冒着重复自己的风险,Spring 在这里真的会帮助抽象。根据您在属性文件中存储的内容,您可能根本不需要它们(如果它们处理配置),或者您将获得一个非常好的 API 来处理它们(如果它们是资源包或类似的东西)。
回答by Itay Maman
Have several places for a properties files and load them (one after another) into a single Properties object. This scheme allow a mapping to have a default value that can then be overridden at several points.
有多个属性文件的位置,并将它们(一个接一个)加载到单个 Properties 对象中。此方案允许映射具有默认值,然后可以在多个点覆盖该值。
回答by akf
The file names can easily be passed in the command line for the app. This can be done either as an arg to the main method(after the main class name) or as a property (as aperkins is alluding, i believe) using the -D flag.
文件名可以轻松地在应用程序的命令行中传递。这可以作为主方法的参数(在主类名之后)或作为属性(因为 aperkins 是暗指,我相信)使用-D 标志来完成。
回答by aperkins
In the past, I have loaded properties through a system property - the file name is passed in through the system property, and I load up that file. There is a default name that we use if the system property is not set. If the file does not exist, then you need to decide what to do there.
过去,我通过系统属性加载了属性——文件名是通过系统属性传入的,然后我加载了那个文件。如果未设置系统属性,我们将使用默认名称。如果该文件不存在,那么您需要决定在那里做什么。
The nice thing about this is there is a standard, but they can override it's location/name using a command line argument.
这样做的好处是有一个标准,但他们可以使用命令行参数覆盖它的位置/名称。
Just my 2 cents though.
虽然只是我的 2 美分。
回答by insitu
I would suggest avoiding using File and filesystem related paths. It is usually better to use classpath paths (hmm, no pun intended...) because: - it makes your code testable by segregating classloaders between runtime and test time, something which is routinely done by any decent build system - it makes your code location independent and allows you to ignore OS issues - it makes your code work the same as a standalone app or within a container (lightweight, servlet, app server, whatever...)
我建议避免使用文件和文件系统相关的路径。通常最好使用类路径路径(嗯,没有双关语......),因为: - 通过在运行时和测试时间之间隔离类加载器,它使您的代码可测试,这是任何体面的构建系统经常完成的事情 - 它使您的代码位置独立并允许您忽略操作系统问题 - 它使您的代码与独立应用程序或在容器内(轻量级、servlet、应用程序服务器,等等)一样工作
You can have a look at the PropertyResourceBundle which has the nice additional feature that is Locale-aware, so you could define different properties with different Locale settings. Note that Locale can be abused to provide parameterization independently of l10n or i18n issues, eg. I used on a project a "windows" and a "linux" locale, because you can construct your own Locale instance and pass it to the loader.
您可以查看 PropertyResourceBundle,它具有很好的附加功能,即区域设置感知,因此您可以使用不同的区域设置定义不同的属性。请注意,可以滥用 Locale 来提供独立于 l10n 或 i18n 问题的参数化,例如。我在一个项目中使用了“windows”和“linux”语言环境,因为您可以构建自己的语言环境实例并将其传递给加载程序。
Or you can just construct the path yourself...
或者你可以自己构建路径......
Or you can load your Properties from an input stream:
或者您可以从输入流加载您的属性:
Properties prop = Properties.load(getClass().getResourceAsStream("/myprops"));
HTH.
哈。

