11

我需要为我目前正在处理的 RMI 应用程序设置代码库,并且首先使用成功完成了这项工作

try{
  ResourceBundle config = ResourceBundle.getBundle("myApp");
  String codeBaseUrl = config.getString("codeBaseUrl");
  System.setProperty("java.rmi.server.codebase", codeBaseUrl);
} catch (Exception e) {
  e.printStackTrace();
}

后来使用

java -Djava.rmi.server.codebase=http://192.168.1.1/path/to/codebase ...

在命令行上。

这两种方法都允许更改代码库而无需重新编译,但 System.setProperty 方法允许将代码库捆绑到属性文件中并使用相同的启动命令。

我读过的大多数教程/文档都使用 -D 方法,这让我相信这被认为是最佳实践,但我一直找不到任何解释为什么我应该使用其他方法的东西。

-D 是否被认为是设置系统属性(如代码库)的最佳实践,这有什么好处/它避免了哪些陷阱?

4

4 回答 4

7

(已编辑 - 我误读了这个问题)

比较两者:

  • -D可配置的 - 它是在运行时指定的
  • 资源包System.setProperty()仍然是“运行时”,但它是通过一个超出启动命令的文件进行编辑的

首先,通过在运行时指定设置来驱动灵活的行为总是比硬编码行为更可取(除非行为实际上并不灵活——即,除非这样做有价值,否则不要使用配置)。

使用文件的主要缺点是它可能包含敏感数据,例如密码,系统管理员不希望这些数据永久存在于磁盘上。如果密码是作为启动命令的一部分输入的,那么它是短暂的并且更加安全(会话命令历史记录不受限制)。

使用文件的好处是您可以建立正确的设置并将它们保留在文件中。您甚至可以通过源代码管理来管理文件。


还有另一个更安全的选择,那就是让启动程序要求在命令行上输入密码,这样就不会留下任何痕迹。

于 2012-09-27T01:21:04.457 回答
4

我会使用 System.setProperty (在应用程序的最顶部,因为对于某些属性,否则可能为时已晚),但从配置文件中获取信息。

您几乎已经这样做了,但我也允许设置任意属性,而不仅仅是一些硬编码的键。

我喜欢将它与我的应用程序已经使用的配置文件结合起来,该文件还包含其他(非 System.properties)设置。我通过在系统属性前面加上 -D 来区分两者(就像在命令行中一样):

 # some configuration
 a.b.c = xxx

 # RMI settings
 -Djava.rmi.server.codebase = http://192.168.1.1/path/to/codebase

将有一个默认位置可以找到此属性文件,但可以通过命令行开关覆盖(以便您可以在不同配置之间切换或轻松安装多个代码)。

拥有一个文件还有一个额外的好处,那就是它也可以用作文档(关于哪些选项可用,它们的默认值是什么等等)。

我真的希望 Java 有一个内置的工具来从属性文件中获取系统属性,以及其他 JVM 设置,如内存和类路径。目前,您必须自己完成所有这些工作,无论是在 Java 中还是在特定于操作系统的 shell 包装器中。

于 2012-09-27T01:45:10.090 回答
2

除非有特殊原因(例如避免暴露敏感信息或防止修改),否则我建议使用“-D”选项而不是使用 System.setProperty 添加属性。

  • 它更简单(更少的代码)
  • 它允许以独立于应用程序的方式直接配置
  • 它避免了在您的应用程序代码有机会设置它们之前在初始化期间读取系统属性的问题。

我的另一个建议是不要将系统属性用作大量特定于应用程序的属性的垃圾场。如果您有很多应用程序配置属性,请使用单独的 Properties 对象(或更复杂的东西)并从单独的属性文件(或更复杂的东西)加载它。其他人可能不同意我的观点,但我发现这是一种更好的方法。

(但显然,如果您使用的是在系统属性中查看的标准或第 3 方子系统,那么这就是您需要做的。)

于 2012-09-27T01:57:02.173 回答
1

因为通过在运行时传入参数,您可以轻松地拥有一个用于开发和生产(以及其他)环境的代码库,而无需将语句硬编码到您的代码中。例如,在开发中您可能想要连接到 192.168.0.1 的服务器,而在生产中您可能想要连接到 10.0.1.1。为了通过使用 System.setProperty 进行硬编码来实现此结果,您需要有条件语句,这可能会变得混乱。

您通常不希望为每个环境重新编译您的应用程序,因此在运行时传递参数或使用可以根据系统更改的某种类型的属性文件通常是最方便的。

于 2012-09-27T01:24:08.697 回答