🗝️ dotenv-kotlin
这是Ruby dotenv项目的Java和Kotlin版本。从.env
文件加载环境变量。
在寻找纯Java版本?获取 dotenv-java。
为什么选择dotenv?
在环境中存储配置是十二要素应用的原则之一。任何可能在不同部署环境之间发生变化的内容——比如数据库的资源句柄或外部服务的凭证——都应该从代码中提取出来,放入环境变量中。
但在开发机器或运行多个项目的持续集成服务器上设置环境变量并不总是切实可行的。Dotenv在环境引导时从.env文件加载变量到ENV中。
主机环境中列出的环境变量会覆盖.env
中的变量。
使用dotenv.get("...")
代替Java的System.getenv(...)
。
安装
如果你在寻找纯Java变体(无Kotlin),请获取dotenv-java。
Maven
<dependency>
<groupId>io.github.cdimascio</groupId>
<artifactId>dotenv-kotlin</artifactId>
<version>6.4.1</version>
</dependency>
Gradle
Gradle Groovy DSL
implementation 'io.github.cdimascio:dotenv-kotlin:6.4.1'
Gradle Kotlin DSL
implementation("io.github.cdimascio:dotenv-kotlin:6.4.1")
使用方法
使用dotenv.get("...")
代替Java的System.getenv(...)
。这是原因。
在项目根目录创建一个.env
文件
# 格式为 key=value
MY_ENV_VAR1=some_value
MY_EVV_VAR2=some_value
使用Java
import io.github.cdimascio.dotenv.Dotenv;
Dotenv dotenv = Dotenv.load();
dotenv.get("MY_ENV_VAR1");
或者使用Kotlin
import io.github.cdimascio.dotenv.dotenv
val dotenv = dotenv()
dotenv["MY_ENV_VAR1"]
Android 使用方法
-
创建一个assets文件夹
-
将
env
(不带点)添加到assets文件夹中。 -
配置dotenv在
/assets
中搜索名为env
的文件val dotenv = dotenv { directory = "/assets" filename = "env" // 使用'env'而不是'.env' } dotenv["MY_ENV_VAR1"]
注意: 需要上述配置是因为在/assets
中的点文件似乎无法在Android上解析。(正在寻求Android社区的建议,关于dotenv-kotlin
配置应如何工作,以便为Android开发者提供最佳体验)
或者,如果你使用Provider android.resource
,你可以指定
directory = "android.resource://com.example.dimascio.myapp/raw"
Flutter 使用方法
建议在Flutter初始化之前在原生Android层使用该包。
- 在
/android/app/src/main/
内创建一个assets文件夹 - 将
env
文件(不带点)添加到assets文件夹中。 - 配置dotenv在./assets目录下搜索名为
env
的文件。
val dotenv = dotenv {
directory = "./assets"
filename = "env" // 使用 'env' 而不是 '.env'
}
dotenv["MY_ENV_VAR1"] ?: ""
- 最佳实践是在仓库中忽略env文件。为此,你可以在android文件夹中使用
.gitignore
高级用法
配置
在应用程序中配置一次 dotenv-kotlin
。
使用 Java
Dotenv dotenv = Dotenv.configure()
.directory("./some/path")
.ignoreIfMalformed()
.ignoreIfMissing()
.load();
- 查看配置选项
或使用 Kotlin
val dotenv = dotenv {
directory = "./some/path"
ignoreIfMalformed = true
ignoreIfMissing = true
}
获取环境变量
注意,主机环境中指定的环境变量优先于 .env
中的变量。
使用 Java
dotenv.get("HOME");
dotenv.get("MY_ENV_VAR1", "default value");
或使用 Kotlin
dotenv["HOME"]
dotenv["MY_ENV_VAR1"] ?: "default value"
遍历环境变量
注意,主机环境中指定的环境变量优先于 .env
中的变量。
使用 Java
for (DotenvEntry e : dotenv.entries()) {
System.out.println(e.getKey());
System.out.println(e.getValue());
}
或使用 Kotlin
for (e in dotenv.entries()) {
println(e.key)
println(e.value)
}
配置选项
可选 directory
-
path
指定包含.env
的目录。Dotenv首先在文件系统上使用给定路径搜索.env
。如果未找到,它会在类路径上搜索给定路径。如果未指定directory
,则默认在文件系统的当前工作目录中搜索。如果未找到,它会在类路径上搜索当前目录。Java 示例
Dotenv .configure() .directory("/some/path") .load()
Kotlin Dsl 示例
dotenv { directory = "/some/path" }
可选 filename
-
使用
.env
以外的文件名。推荐用于Android(参见详情)Java 示例
Dotenv .configure() .filename("myenv") .load();
Kotlin Dsl 示例
dotenv { filename = "myenv" }
可选 ignoreIfMalformed
-
当
.env
条目格式错误时不抛出异常。格式错误的条目将被跳过。Java 示例
Dotenv .configure() .ignoreIfMalformed() .load();
Kotlin Dsl 示例
dotenv { ignoreIfMalformed = true }
可选 ignoreIfMissing
-
当
.env
不存在时不抛出异常。Dotenv将继续检索在环境中设置的环境变量,例如dotenv["HOME"]
Java 示例
Dotenv .configure() .ignoreIfMissing() .load();
Kotlin Dsl 示例
dotenv { ignoreIfMissing = true }
可选 systemProperties
-
将环境变量加载到系统属性中,从而使所有环境变量可通过
System.getProperty(...)
访问Java 示例
Dotenv .configure() .systemProperties() .load();
Kotlin Dsl 示例
dotenv { systemProperties = true }
示例
- 使用 Maven (简单)
- 使用 Spring MVC
- 使用 Spring Webflux
- 使用 Android
- 参见 Kotlin DSL 测试
- 参见 Java 测试
常见问题
问: 我应该将 .env
部署到生产环境吗?
答: 12因素应用方法论的第三条原则指出:"12因素应用将配置存储在环境变量中"。因此,不建议向这些环境提供.env文件。然而,dotenv在本地开发环境中非常有用,因为它使开发人员能够通过文件管理环境,这更加方便。
在生产环境中使用dotenv是一种取巧的做法。这种用法实际上是一种反模式。
问: 为什么我应该使用 dotenv.get("MY_ENV_VAR")
而不是 System.getenv("MY_ENV_VAR")
?
答: 由于Java不提供在当前运行的进程上设置环境变量的方法,因此无法设置 .env
中列出的变量,也就无法使用 System.getenv(...)
检索这些变量。
问: 我可以使用 System.getProperty(...)
来检索环境变量吗?
答: 当然可以。使用 systemProperties
选项。或者在初始化dotenv后,手动将每个环境变量设置到系统属性中。例如:
Java
Dotenv dotenv = Dotenv.configure().load();
dotenv.entries().forEach(e -> System.setProperty(e.getKey(), e.getValue()));
System.getProperty("MY_VAR");
Kotlin
val dotenv = dotenv()
dotenv.entries().forEach { (key, value) -> System.setProperty(key, value) }
**问:**我应该使用多个.env文件吗?
**答:**不。我们强烈建议不要使用一个"主要"的.env文件和一个"环境"的.env文件,如.env.test。你的配置应该在不同的部署之间有所变化,而且你不应该在不同环境之间共享值。
在一个遵循十二要素应用的程序中,环境变量是细粒度的控制,每个变量都完全独立于其他环境变量。它们从不被归类为"环境",而是为每次部署独立管理。这是一种随着应用在其生命周期内自然扩展到更多部署时能够平滑扩展的模型。
– 十二要素应用
**问:**我应该提交我的.env
文件吗?
**答:**不。我们强烈建议不要将你的.env
文件提交到版本控制系统。它应该只包含特定环境的值,如数据库密码或API密钥。你的生产数据库应该有一个不同于开发数据库的密码。
**问:**对于已经设置的环境变量会发生什么?
**答:**dotenv-kotlin永远不会修改任何已经设置的环境变量。特别是,如果你的.env
文件中有一个变量与已存在于你环境中的变量冲突,那么该变量将被跳过。这种行为允许你用特定机器的环境覆盖所有.env
配置,尽管不推荐这样做。
问:.env
中的变量扩展怎么处理?
**答:**我们还没有遇到一个令人信服的变量扩展用例,并且认为它会导致环境变量不是"完全正交的",正如十二要素应用所概述的。如果你有一个令人信服的用例,请开一个issue。
**问:**我可以提供多行值吗?
**答:**dotenv-kotlin表现出与Java的System.getenv(...)
相同的行为,因此如果需要多行值,你可以考虑通过例如Base64进行编码。详情请参见这个评论。
**注意和参考:**上面的FAQ中包含了来自motdotla的dotenv Node项目页面上的相关FAQ,因为它们做得非常好。
贡献者
欢迎贡献!
许可证
参见 LICENSE (Apache 2.0)