跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

怎么通过 System.getenv() 与 System.getProperty() 的协同工作实现多级配置变量覆盖

环境变量 > JVM参数 > 代码默认值构成三级配置覆盖链,推荐封装统一读取工具方法按序查找,并统一键名风格为大写+下划线以保障跨平台一致性。 可以通过环境变量(
System.getenv()
)优先覆盖 Java 系统属性(
System.getProperty()
),再由系统属性覆盖硬编码默认值,形成“环境变量 > JVM 参数 > 代码默认值”的三级配置覆盖链。 明确覆盖优先级与用途分工 环境变量适合部署时差异化配置(如不同服务器的数据库地址),JVM 参数(
-Dkey=value
)适合启动时动态指定(如测试环境开关),而代码中默认值仅作兜底。三者不互斥,应按需组合使用,避免在代码中混用
getenv
和
getProperty
做相同键名的无序读取。 统一读取封装:优先查环境变量,未命中再查系统属性 推荐封装一个工具方法,按固定顺序查找,避免各处逻辑不一致:
public static String getConfig(String key, String defaultValue) { // 1. 先查环境变量(最高优先级) String envValue = System.getenv(key); if (envValue != null && !envValue.trim().isEmpty()) { return envValue.trim(); } // 2. 再查 JVM 系统属性(-Dkey=value) String propValue = System.getProperty(key); if (propValue != null && !propValue.trim().isEmpty()) { return propValue.trim(); } // 3. 返回硬编码默认值 return defaultValue; }
调用示例:
getConfig("DB_URL", "jdbc:h2:mem:test")
—— 若环境中有
DB_URL= jdbc:mysql://prod:3306/app
,则直接返回该值;否则查
-DDB_URL=...
;都未设置才用 H2 默认库。 注意键名大小写与命名规范 环境变量在 Linux/macOS 中通常全大写并用下划线(如
REDIS_HOST
),而 JVM 属性习惯用小写加点号(如
redis.host
)。若想复用同一套配置逻辑,建议统一键名风格: 方案一(推荐):约定所有配置项使用大写+下划线(如
APP_TIMEOUT_MS
),环境变量和 JVM 参数均按此命名(启动时传
-DAPP_TIMEOUT_MS=5000
) 方案二:做映射转换,例如将
redis.host
自动转为
REDIS_HOST
查环境变量,但需注意平台兼容性(Windows 环境变量不区分大小写,Linux 区分) 配合 Spring Boot 或其他框架时的注意事项 Spring Boot 默认已内置类似机制(支持
ENV
、
systemProperties
、
systemEnvironment
多源合并),若手动使用
System.getenv
/
System.getProperty
,需注意: 不要在
@Value
或
@ConfigurationProperties
中混用原始 API,应统一走 Spring 的 Environment 抽象 若必须手动读取(如静态工具类初始化),确保在 Spring Context 创建前完成,或使用
@PostConstruct
延迟加载 JVM 参数需在
java -D...
启动时传入,不能在运行时通过
System.setProperty
修改后影响已读取的配置(除非重新触发读取逻辑)

相关文章