跨类提供Java属性?

时间:2011-01-20 16:59:18

标签: java properties

我选择使用属性文件来自定义某些设置。 我使用以下代码在类

中创建一个属性对象
Properties defaultProps = new Properties();
    try {
        FileInputStream in = new FileInputStream("custom.properties");
        defaultProps.load(in);
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

我是否必须将此添加到每个班级?可能不是因为那时每个类都会打开一个流到这个文件。 但我不确定如何妥善处理这个问题。 我应该创建一个类MyProperties并在任何类需要属性中实例化它吗?

提前致谢!

8 个答案:

答案 0 :(得分:12)

初始化defaultProps后,您可以将其内容提供给应用中的其他对象,例如通过公共静态访问器方法,例如:

public class Config {
  private static Properties defaultProps = new Properties();
  static {
    try {
        FileInputStream in = new FileInputStream("custom.properties");
        defaultProps.load(in);
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
  }
  public static String getProperty(String key) {
    return defaultProps.getProperty(key);
  }
}

这是最简单的方法,但它会创建一个额外的依赖项,这会使单元测试更加困难(除非您在Config中提供一个方法来设置单元测试的模拟属性对象。)

另一种方法是将defaultProps(或其中的各个配置值)注入需要它的每个对象。但是,这可能意味着如果您的调用层次结构较深,则需要在许多方法中添加额外的参数。

答案 1 :(得分:3)

如果您只需要一个属性类实例,则可以使用singleton pattern

它看起来像这样的一个类:

public class MyProperties extends Properties {
    private static MyProperties instance = null;

    private MyProperties() {
    }

    public static MyProperties getInstance() {
        if (instance == null) {
            try {
                instance = new MyProperties();
                FileInputStream in = new FileInputStream("custom.properties");
                instance.load(in);
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        return instance;
    }
}

答案 2 :(得分:1)

为什么不使用静态ResourceBundle?

static final ResourceBundle myResources = 
          ResourceBundle.getBundle("MyResources", currentLocale);

答案 3 :(得分:0)

确定处理此问题的最佳方法的信息太少。您可能希望使用访问器公开它,或将其传递到需要它的每个类中。或者,您可以提取每个类所需的属性,并将它们的值传递给类的构造函数。

答案 4 :(得分:0)

使用并加载属性,并存储其他类可以从中拉出的属性。如果那是一个MyProperties类,它引用一个很好的静态变量。

答案 5 :(得分:0)

这是在全球范围内提供任何可用内容的特殊情况。使用静态方法非常糟糕。一个更好但不好的解决方案是使用sigleton模式。测试是这里最大的问题。恕我直言,最好的方法是使用Dependency injection,尽管对于小型应用程序来说可能有点过头了。

答案 6 :(得分:0)

由于此信息在所有实例中都是静态的,因此我建议将Properties类实现为singleton。通过使用static initialization block方法,您可以在程序启动时自动加载文件。

public class Properties {
  static {
    try {
      FileInputStream in = new FileInputStream("custom.properties");
      load(in);
      in.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  protected static void load(FileInputStream in) {
    // existing load functionality here
  }
}

您仍然需要内部存储机制和访问机制。这些也应标记为static

答案 7 :(得分:0)

而不是在每个类中加载属性。将它加载到main()周围的某处,并通过它们的构造函数将它传递给其他类。

不要在全球分享它们。   - 难以测试   - 反对抽象(全局访问,DAO可以访问用户设置。应该通过只传递它需要的东西来阻止它...而不是所有东西)   - 课程就是他们需要的东西