跨类提供Java属性?

我选择使用属性文件来自定义某些设置。 我使用以下代码在类中创建一个Properties对象

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

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

提前致谢!

初始化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); } } 

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

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

如果只需要属性类的一个实例,则可以使用单例模式 。

它看起来像这样的类:

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

为什么不使用静态ResourceBundle?

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

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

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

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

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

 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

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

不要在全球范围内分享。 – 难以测试 – 反对抽象(全局访问,DAO可以访问用户设置。应该通过仅传递它需要的东西来防止…而不是所有东西) – 类是他们需要的