我有几个类需要加载一些属性文件,我想知道实现这一目标的最佳实践是什么。我想到了两种基本方法:
对每个类中的属性文件名进行硬编码,然后使用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. } }
然而,可能还有许多其他更优雅的方法,这就是我提出这些问题的原因:i)在Java中加载属性文件的最佳实践是什么? ii)你是否使用任何照顾工作的帮助班? iii)你在(在代码中)通常加载属性文件吗?
此外,类可以“自动加载”其属性吗?或者我应该将我需要的参数传递给构造函数?传递参数的问题在于,某些类(~20,表示统计模型中的参数)的方法太多了。
答案 0 :(得分:7)
最佳做法是使用某种dependency injection容器 - 例如Spring Framework或Google Guice。
它解决了各种问题 - 你没有把你的类绑定到特定的属性文件名,你不必担心在该类中加载所述属性并处理可能的异常,你不必通过30个属性文件名作为命令行参数(或系统属性)。
除了属性加载之外,它还可以帮助许多其他东西:-) - 尝试一下,你会想知道你是如何生活的。
更新:顺便说一句,your other question也是Spring会照顾的事情之一。
更新#2:我刚刚意识到我对你already tried to push Spring :-)冒着重复自己的风险,Spring会真正帮助抽象。根据您在属性文件中存储的内容,您可能根本不需要它们(如果它们处理配置),或者您将获得一个非常好的API来处理它们(如果它们是资源包或类似的东西)。
答案 1 :(得分:1)
为属性文件提供多个位置并将它们(一个接一个地)加载到单个Properties对象中。此方案允许映射具有默认值,然后可以在多个点覆盖该默认值。
答案 2 :(得分:1)
可以在应用程序的命令行中轻松传递文件名。这可以使用arg to the main method作为-D flag(在主类名之后)或作为属性(如aperkins暗示,我相信)使用{{3}}。
答案 3 :(得分:0)
过去,我通过系统属性加载了属性 - 文件名通过系统属性传入,然后我加载该文件。如果未设置系统属性,则使用默认名称。如果该文件不存在,那么您需要决定该做什么。
关于这一点的好处是有一个标准,但是他们可以使用命令行参数覆盖它的位置/名称。
虽然只是我的2美分。
答案 4 :(得分:0)
我建议避免使用与文件和文件系统相关的路径。通常最好使用类路径路径(嗯,没有双关语......)因为: - 它通过在运行时和测试时间之间隔离类加载器来使代码可测试,这通常由任何体面的构建系统完成 - 它使您的代码位置独立,并允许您忽略操作系统问题 - 它使您的代码与独立应用程序或容器内的工作方式相同(轻量级,servlet,app服务器,等等......)
您可以查看PropertyResourceBundle,它具有可识别区域设置的附加功能,因此您可以使用不同的区域设置定义不同的属性。请注意,可以滥用Locale来独立于l10n或i18n问题提供参数化,例如。我在项目中使用了“windows”和“linux”语言环境,因为您可以构建自己的Locale实例并将其传递给加载器。
或者你可以自己构建路径......
或者您可以从输入流加载属性:
Properties prop = Properties.load(getClass().getResourceAsStream("/myprops"));
HTH。