加载属性的最佳策略是什么?

时间:2009-08-04 22:34:27

标签: java properties

我有几个类需要加载一些属性文件,我想知道实现这一目标的最佳实践是什么。我想到了两种基本方法:

  • 对每个类中的属性文件名进行硬编码,然后使用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,表示统计模型中的参数)的方法太多了。

5 个答案:

答案 0 :(得分:7)

最佳做法是使用某种dependency injection容器 - 例如Spring FrameworkGoogle 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。