【问题标题】:How to manage application.conf in several environments with play 2.0?如何使用 play 2.0 在多个环境中管理 application.conf?
【发布时间】:2012-03-15 15:45:45
【问题描述】:

使用 Play 1.2,我可以在配置键前面加上框架 ID 或应用程序模式,如下所示:

# Production configuration
%prod.http.port=80
%prod.application.log=INFO
%prod.application.mode=prod

但它似乎不适用于 2.0。

有没有办法让它工作?

【问题讨论】:

标签: playframework-2.0


【解决方案1】:

Play 2 不会强迫您使用任何特定的方法来管理您的环境。但它为您提供了强大而灵活的工具,可以根据您的项目需求自行实施。

例如,一种常见的模式是在一个文件中保留常见的环境设置,并在其他文件中具有特定于环境的覆盖。为此,您需要custom Global object(您可以将其直接放入./app/Global.scala)。以下代码自 Play 2.1.1 (Scala 2.10) 起有效:

import java.io.File
import play.api._
import com.typesafe.config.ConfigFactory

object Global extends GlobalSettings {
  override def onLoadConfig(config: Configuration, path: File, classloader: ClassLoader, mode: Mode.Mode): Configuration = {
    val modeSpecificConfig = config ++ Configuration(ConfigFactory.load(s"application.${mode.toString.toLowerCase}.conf"))
    super.onLoadConfig(modeSpecificConfig, path, classloader, mode)
  }
}

现在您可以将 application.dev.confapplication.test.confapplication.prod.conf 放入您的 ./conf 中,并使用特定于环境的覆盖(同时在 application.conf 中保留常用设置)。

在这个示例中,我们依赖于 Play 自己的 mode,这通常是有意义的,但您可以根据需要使用环境变量或任何您喜欢的东西。

另见:Typesafe Config

【讨论】:

  • 太棒了!谢谢。
  • 这似乎对我不起作用。当我使用此代码时,模式覆盖文件中未设置的任何内容似乎都设置为播放默认值,而不是 application.conf 中的内容。我正在使用play 2.2.1 built with Scala 2.10.2 (running Java 1.7.0_45)。其他人可以确认这种行为吗?我认为这与ConfigFactory.load有关。
  • 查看 ConfigFactory 的文档,我看到了 ConfigFactory.load(String):Loads an application's configuration from the given classpath resource or classpath resource basename, sandwiches it between default reference config and default overrides, and then resolves it.
  • 是的,我就是这么做的。请阅读我的其他 cmets。我说过我是如何让它与我的版本一起工作的。
  • 这似乎已被弃用,根据文档:“此方法不做任何事情。相反,在您的配置文件中指定配置或制作您自己的 ApplicationLoader(请参阅 GuiceApplicationBuilder.loadConfig)”
【解决方案2】:

我也有这个问题很长时间了,下面是我迄今为止学到的最好的方法,当我在 Play 2 google group 上提出类似问题时得到了提示。

在您的 application.config 中,当系统参数存在时,使用以下语法覆盖配置值:

# Local machine fallback URI
mongodb.uri="mongodb://192.168.56.101:27017/application"
# Env variable override
mongodb.uri=${?MONGOLAB_URI}

问号表示如果未设置 env 变量,则不会覆盖它。如果您只使用 ${MONGOLAB_URI} 您希望设置变量,我假设如果未设置,您会遇到某种异常。

为了完整起见,以下是您如何读取值的示例:

lazy val mongoUri = current.configuration.getString("mongodb.uri").getOrElse("mongodb:///")

使用这种方法有一个警告:确保将系统参数配置保存在某种 SCM 中。

【讨论】:

  • 嗨 Magnus - 我如何在 application.conf 中创建一个等于 mongodb.uri 但添加了 /a.xml 的新环境变量?
  • @KevinMeredith:我知道这是一个非常老的评论,但是..你可以使用my_new_cfg = ${mongodb.uri}"/a.xml"之类的东西。当然,这是假设您使用 HOCON 格式进行类型安全配置。
【解决方案3】:

您必须使用适当的属性定义不同的配置文件

http://www.playframework.org/documentation/2.0/Configuration

还有一个包含机制,可以帮助您在 application.conf 中定义默认值并仅覆盖生产所需的内容

【讨论】:

  • 我试图这样做,我面临的唯一问题是当我在application.confprod.conf 中都有db.default.driver, db.default.url, db.default.user, etc 时,prod.conf 的某些原因它永远不会连接。但是当我从 application.conf 中删除数据库设置并运行 prod.conf 时,它可以工作。这是有原因的吗?
  • 顺便说一句,我有prod.conf,包括application.conf
  • 是的,Play 2 似乎不允许您覆盖默认数据库参数。
【解决方案4】:

如果您想独立于重新限制的 scala 运行模式,您可以使用 JVM 属性。 将修改后的@coffesnake 示例放到 ./app/Global.scala 中:

import java.io.File

import play.api._
import com.typesafe.config.ConfigFactory

object Global extends GlobalSettings {
  override def onLoadConfig(config: Configuration, path: File, classloader: ClassLoader, mode: Mode.Mode): Configuration = {
    val environment = System.getProperty("environment")
    val environmentSpecificConfig = config ++ Configuration(ConfigFactory.load(s"application.${environment}.conf"))
    super.onLoadConfig(environmentSpecificConfig, path, classloader, mode)
  }
}

下一场比赛play

并使用环境参数run -Denvironment=prod-server1启动应用程序

不要同时加入这两个命令,这样就不行了

全局配置将被文件中的环境特定属性覆盖:

./conf/application.prod-server1.conf

编辑:

从时间的角度来看,我认为这种解决方法是不必要的。最好使用 Play 内置配置加载机制 -Dconfig.file=/etc/play-application/foo-production.conf

【讨论】:

    【解决方案5】:

    我正在使用这个解决方案:

    application.conf我已经定义了默认配置, 在myUsername.conf 我已经包含了默认配置并覆盖了用户特定的配置:

    include "application.conf"
    logger.application=DEBUG
    

    然后在Global.java 我已经加载了用户特定的配置(如果存在):

    public Configuration onLoadConfig(Configuration config, File path,
            ClassLoader classloader) {
    
        String username = System.getProperty("user.name");
        File confFile = new File(new File(path, "conf"), username + ".conf");
    
        if (confFile.exists()) {
            Logger.info("configuration file {} found", confFile.getName());
            return new Configuration(ConfigFactory.load(confFile.getName()));
        } else {
            Logger.info(
                    "configuration file {} not found, using default application.conf",
                    confFile.getAbsolutePath());
            return null;
        }
    
    }
    

    【讨论】:

      【解决方案6】:

      我们只有多个 application.conf 文件,在开发过程中使用默认值,我们有一个 prod-application.conf,我们在部署时只需将其复制到适当的位置。

      【讨论】:

      • 这工作正常,但需要团队保持这两个文件彼此同步
      猜你喜欢
      • 2013-01-17
      • 1970-01-01
      • 2021-09-05
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 2021-04-20
      • 2023-01-17
      相关资源
      最近更新 更多