【问题标题】:How to read "OS variables" from Java (not System.properties)如何从 Java(不是 System.properties)中读取“操作系统变量”
【发布时间】:2014-09-22 01:37:09
【问题描述】:

我刚刚阅读了出色的 12 Factor App 文档,它确实在我这里注册了。在Chapter 3 Config中,作者强调:

十二因素应用程序将配置存储在环境变量中(通常缩写为 env vars 或 env)。环境变量很容易在部署之间更改,而无需更改任何代码;与配置文件不同,它们被意外签入代码仓库的可能性很小;与自定义配置文件或其他配置机制(如 Java 系统属性)不同,它们是与语言和操作系统无关的标准。

我想知道这对 Java 项目意味着什么。

通常,当涉及到我的 Java 应用程序时,我认为“环境变量”是我可以从 System.getProperty("blah") 读取的内容。这就是作者在说的吗?我不认为是这样,因为作者明确指出“不像...或其他配置机制,如 Java System Properties...”。

如果不是,那么满足本文档对“env var”定义的与操作系统无关的“env var”的示例是什么?我如何从 Java 代码中读取它?

无论哪种方式,某些进程必须首先在操作系统上设置每个 env var,以便在应用程序运行时设置和可用 var。哪些流程/方法可以进行此类预运行设置?

【问题讨论】:

  • Spring 以一种干净、透明的方式处理所有这些:foo.value 可以从名为 foo.value 的属性或名为 foo_value 的环境变量中映射。此外,即使您不使用 Spring,也请查看 Spring Cloud,它会自动处理大量此类注入。

标签: java environment-variables configuration-files system-properties 12factor


【解决方案1】:

使用System.getenv() 而不是System.getProperty()System.getenv() 返回操作系统中定义的指定环境变量的值。

其他可能更可取的方法是使用-D 命令开关将选定的操作系统环境变量传递给您的JVM,然后使用System.getProperty() 检索它们。这种方式更加跨平台:即使特定平台不支持特定变量,您也可以使用相同的 java 代码。

更新操作系统变量绝对是另一项任务。首先,我不认为你真的想这样做。如果您仍然想尝试问另一个问题:可能存在其他解决方案。

在 JDK 中没有跨平台 API 可以做到这一点,而且我不知道 3rd 方库也会死掉。我个人计划实施一个,但到目前为止还没有时间。

Windows 将变量存储在注册表中,因此您可以将变量添加到注册表。但这不会影响 shell 的当前实例,因此您自己的 java 进程不会看到它自己更新的变量。但是,您可以创建进程并运行SET myvar=myvalue。如果您想写入注册表,您可以使用任何可用的库。有时我也实现了这样的库。它的优点是它不运行任何本机代码并且非常紧凑。看看here

在 Unix 上你可以运行myvar=myvalue,如果你想让其他进程看到这个变量你必须运行export myvar。但它仍然没有使这个变量持续存在。如果您希望此变量在操作系统重新启动后仍然存在,您必须将其添加到初始脚本之一(例如.bashrc)。但这完全取决于您的系统、配置、权限、shell 等。

【讨论】:

  • 感谢@AlexR (+1) - 但我将如何首先在操作系统本身上 设置 特定于应用程序的环境变量(以便 System.getenv() 可以找到/读取它们) ?假设我们希望应用在 Windows 7 和 Linux(Ubuntu 等)上运行?
  • 再次感谢@AlexR - 所以如果我想要一个变量为fizz.buzz,我将如何运行我的应用程序?像这样的东西:java -jar myapp.jar -Dfizz.buzz=true?
  • 谢谢 AlexR 我喜欢你的第二个解决方案(使用命令开关)。它似乎符合 12 Factor 原则并且是跨平台的。
  • java -cp YOURCLASSPATH -Dfizz.buzz=true com.bla.Main
【解决方案2】:

是的,作者说的是环境变量。您可以使用以下 sn-p 从 java 代码中读取环境变量:

System.getenv(env);

见:http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#getenv-java.lang.String-

如果你想要操作系统不可知的方式,你可以使用 JVM 参数并使用

System.getProperties();

例如,如果要传递名为var1 的变量,请使用java -Dvar1=true -jar myJar.jar

【讨论】:

  • 谢谢@vivek_ganesan (+1) - 但请在 AlexR 的回答下方查看我的评论 - 我有同样的问题要问你!
猜你喜欢
  • 1970-01-01
  • 2022-01-14
  • 2010-10-02
  • 2014-01-03
  • 1970-01-01
  • 1970-01-01
  • 2012-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多