如何使用IntelliJ在环境特定的运行时配置之间轻松切换?

时间:2014-02-04 16:12:34

标签: java spring configuration intellij-idea classpath

在我工作的大多数Java项目(Maven,Spring)中,我有以下要求:

  • 打包的jar需要在多个环境中运行,例如dev,beta,prod
  • 不得为每个环境重建jar
  • 每个环境都需要不同的配置属性
  • 在开发过程中,我需要能够在不同环境之间轻松切换,以确保在部署之前正确配置每个环境

到目前为止,我已经通过将所有配置属性放入单独的属性文件(每个环境一个)来完成此操作。然后我从类路径中加载这些文件中的Spring。然后我只需在运行时更改类路径以加载所需的属性。

当我使用Eclipse时,这种方法运行良好,因为很容易设置多个运行配置并改变每个运行配置的类路径。完成此操作后,切换环境就是选择相关的运行配置。

不幸的是,这在IntelliJ中要难得多,因为运行时依赖只能添加到模块的配置(as documented in this answer)。如果我尝试在运行配置本身中设置类路径,那么这将覆盖所有模块依赖项,从而阻止应用程序运行(as documented here)。因此,要切换环境,我每次都必须重新编辑模块依赖项。

使用IntelliJ有更简单的方法吗?

如果没有,那是因为我的配置要求或我的解决方案是不寻常的吗?在哪种情况下,有更好的方法吗?

以前的方法

我已经尝试过并拒绝了许多方法:

  • Maven配置文件 - 每当我想切换环境时,这些都需要重建我的jar。除了烦人和危险之外,这似乎完全不适合运行时配置(但对于构建时配置是理想的)。这似乎是冒着将破坏的构建投入到生产中的一种很好的方法,因为您没有针对实际部署的相同jar进行测试。呸!

  • Spring配置文件 - 这些看起来更合适,但似乎要求所有配置都与jar一起部署并通过文件名区分,例如dev.properties,prod.properties。然后,您可以通过在运行时传递变量来选择所需的那个。这要好得多,但我不希望我的prod.properties找到进入版本控制的方式,也不希望使用jar本身进行部署。因此,似乎仍然需要修改类路径以包含它们在IntelliJ中我不能轻易做到的

2 个答案:

答案 0 :(得分:1)

当我遇到类似问题时,我开始使用帮助程序类加载我的属性。辅助类将查找System属性,该属性包含环境或从中加载属性的绝对/类路径相对路径。

这样,代码总是相同的,我不必更改项目的配置。我只是使用不同的启动配置来设置不同的属性。

这里的主要缺点当然是测试/ dev配置泄漏到prod。使用Maven,简单的解决方案是将它们移动到一个新模块中,并将其范围设置为provided。这样,模块将在Maven内部可见,但在WAR包装等期间不会包含该模块。

答案 1 :(得分:1)

我做了类似于@AaronDigulla的事情,但我覆盖属性。那就是我首先从类路径中的属性文件中加载所有属性(使用Spring)。然后我搜索特定的变量名称和值(按以下顺序):

  1. 在servlet init参数中
  2. 然后在系统属性
  3. 最后是环境变量
  4. 此变量名称和值包含属性文件的路径,这些文件将覆盖/覆盖从类路径加载的属性。此外,每个加载的属性都将执行相同类型的解析(即系统属性,环境变量和servlet init参数覆盖属性文件中的属性)。

    现在所有开发人员都被推到使用类路径中的默认配置(即为他们的数据库使用相同的用户名/密码)。具有不同设置的那些可以使用以上3种不同的方式来覆盖。

    我使用的

    You can use the same bootstrapping configuration code将首先加载classpath*:META-INF/spring/*.properties中的所有属性文件然后它将加载所有属性文件,其中文件/类路径URL在名为{{的property / environment / init参数变量中设置。 1}}(如果设置)。

    然后最后在加载属性文件之后,它将通过拉动名为MyConfigParameter的属性/ environment / init参数(逗号分隔)来设置Spring配置文件。

    因此,在生产中,您可以设置环境变量MyConfig.profiles

    然后在其中一个属性文件中,您可以设置MyConfigParameter=file://etc/myapp/*.properties,这将设置Spring个人资料MyConfig.profiles=production,postgresproduction

    用于在构建计算机上发布/构建的Maven配置文件显然可以使用“系统属性”调整环境中的postgres。但是你必须告诉surefire单元测试这个属性(特别是如果分叉):

    MyConfigParameter