Scala 中按环境的特定配置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21607745/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 06:03:21  来源:igfitidea点击:

specific config by environment in Scala

scalaconfigurationenvironment-variablesconfigdevelopment-environment

提问by Daniel Cukier

What is a good way to set up a project in Scala which uses different configuration depending on environments.

在 Scala 中设置项目的好方法是什么,它根据环境使用不同的配置。

I need to specifically have different databases for development, testand productionenvironment (similar to what is done in Rails)

我需要专门有不同的数据库用于开发测试生产环境(类似于在 Rails 中所做的)

回答by ozeebee

Another strategy I'm using consists of using includes. I usually store my DEV settings in the defaultapplication.conffile then I create a new conf file for other environments and include the default one.

我正在使用的另一个策略是使用includes。我通常将我的 DEV 设置存储在默认application.conf文件中,然后我为其他环境创建一个新的 conf 文件并包含默认文件。

Let's say my DEV conf application.conflooks like this:

假设我的 DEV confapplication.conf如下所示:

myapp {
    server-address = "localhost"
    server-port = 9000

    some-other-setting = "cool !"
}

Then for the PROD, I could have another file called prod.conf:

然后对于 PROD,我可以有另一个名为的文件prod.conf

include "application"

# override default (DEV) settings
myapp {
    server-address = ${PROD_SERVER_HOSTNAME}
    server-port = ${PROD_SERVER_PORT}
}

Note that I override onlythe settings that change in the PROD environment (some-other-settingis thus the same as in DEV).

请注意,我覆盖在 PROD 环境中更改的设置(some-other-setting因此与 DEV 中的设置相同)。

The config bootstrap code doesn't test anything

配置引导代码不测试任何东西

...
val conf = ConfigFactory.load()
...

To switch from the DEV to the PROD conf, simply pass a system property with the name of the config file to load:

要从 DEV 切换到 PROD conf,只需传递一个带有要加载的配置文件名称的系统属性:

java -Dconfig.resource=prod.conf ...

In DEV, no need to pass it since application.confwill be loaded by default.

在 DEV 中,不需要传递它,因为它application.conf默认加载。

So here we're using Typesafe Config's default loading mechanism to achieve this.

所以在这里我们使用Typesafe Config的默认加载机制来实现这一点。

I've created a simple projectto demonstrate this technique. Feel free to clone and experiment.

我创建了一个简单的项目来演示这种技术。随意克隆和实验。

回答by Daniel Cukier

Use typesafe Config. Create a Config object like this:

使用类型安全配置。像这样创建一个 Config 对象:

import com.typesafe.config._

object Config {
  val env = if (System.getenv("SCALA_ENV") == null) "development" else System.getenv("SCALA_ENV")

  val conf = ConfigFactory.load()
  def apply() = conf.getConfig(env)
}

Then create the application.conffile in src/main/resourcesfolder:

然后在application.conf文件src/main/resources夹中创建文件:

development {
  your_app {
    databaseUrl = "jdbc:mysql://localhost:3306/dev_db"
    databaseUser = "xxxx"
    databasePassword = "xxxx"
  }
}
test {
  your_app {
    databaseUrl = "jdbc:mysql://localhost:3306/test_db"
    databaseUser = "xxxxx"
    databasePassword = "xxxx"
  }
}

Now from anywhere in your application, you can access configuration:

现在,您可以从应用程序的任何位置访问配置:

Config().getString("your_app.databaseUrl")

Config().getString("your_app.databaseUrl")

If you have your environment set up (e.g. export SCALA_ENV=test) when you run your application, it will consider the right configuration section. The default is development

如果您export SCALA_ENV=test在运行应用程序时设置了环境(例如),它将考虑正确的配置部分。默认是开发

回答by DHa

I wasn't happy with how Daniel Cukiers solution did not allow defaults and overrides, so I changed it around to make full use of those.

我对 Daniel Cukiers 解决方案不允许默认值和覆盖的方式感到不满意,因此我对其进行了更改以充分利用这些。

The only configuration you have to do is set a ENVIRONMENT variable on the system (defaults to 'dev' if none is set)

您唯一需要做的配置是在系统上设置一个 ENVIRONMENT 变量(如果没有设置,则默认为“dev”)

(Java solution, compatible with Scala):

(Java解决方案,兼容Scala):

import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;

public class MyCompanyConfig {
    public final static Config base = ConfigFactory.load().getConfig("mycompany");
    public final static String environment = System.getenv("ENVIRONMENT") == null ? "dev" : System.getenv("ENVIRONMENT");

    /**
     * Returns a subtree of the base configuration with environment settings applied.
     *
     * @param setting The subtree to return config for.
     * @return A config with base in given setting, with environment modifications applied.
     */
    public static Config load(String setting) {

        Config config = base.getConfig(setting);

        if (config.hasPath(environment)) {
            return config.getConfig(environment).withFallback(config);
        }

        return config;
    }
}

This allows a single reference.conf in a library looking like this:

这允许库中的单个 reference.conf 如下所示:

mycompany.module1 {
    setting1 : "adefaultvalue"
    url : "localhost"

    test {
        // will be used where ENVIRONMENT="test"
        url : "test.mycompany.com"
    }

    prod {
        // will be used where ENVIRONMENT="prod"
        setting1 : "changethedefault"
        url : "www.mycompany.com"
    }
}

Usage:

用法:

Config conf = MyCompanyConfig.load("module1")