Java 配置管理
配置与代码分离:来源优先级、类型安全与可测试注入。
#concept
#growing
#dev
#java
[!info] related notes
Java 配置管理
这个概念为什么出现
同一构件要跑在 dev/stage/prod:端口、数据库 URL、特性开关不同。配置必须外置,且可测试、可审计。
[!abstract] 一句话理解 配置从环境/文件/启动参数注入,与代码分离;明确优先级与类型转换,密钥不进仓库。
最小可运行示例
场景:从环境变量读服务端口,未设置时缺省 8080
public class PortConfig {
static int port() {
String raw = System.getenv().getOrDefault("APP_PORT", "8080");
int p = Integer.parseInt(raw);
if (p < 1 || p > 65535) throw new IllegalArgumentException("bad port");
return p;
}
public static void main(String[] args) {
System.out.println(port());
}
}
javac PortConfig.java && APP_PORT=9090 java PortConfig
期望:
9090
此命令使用 POSIX shell 的临时环境变量语法。缺失 APP_PORT 才取默认值;空串、带空格或非整数内容会解析失败,越界值会被拒绝。这里选择 1–65535 作为固定服务端口契约;某些套接字 API 支持的端口 0(自动分配)不在本例范围内。
结合场景再看三个关注点
- 缺省值要安全。
- 校验失败要快死在启动期。
- 密钥用密钥管理,不是明文 properties 提交。
核心概念与准确模型
1. 来源
env 用 System.getenv 读取;java -Dapp.port=9090 Main 设置的系统属性用 System.getProperty("app.port") 读取。二者不是同一命名空间,本例只读取 env;配置文件/远程中心需要应用或框架加载。
2. 优先级
Java 不为这些来源规定统一覆盖顺序;应用或框架决定优先级,团队应写明实际版本下的规则。
3. 类型安全
解析后还需检查范围与单位;例如 Boolean.parseBoolean 对忽略大小写后不等于 true 的文本返回 false,不会拒绝拼写错误。必须严格校验的开关应显式限定合法值。框架绑定到对象也不自动完成所有业务校验。
边界情况与反直觉行为
- 容器与本地 env 注入差异。
- 多文档 yaml 合并坑。
- System.getenv 是进程看到的环境,不会随部署平台后续修改而自动刷新;动态配置应单独定义刷新与一致性契约。
常见误区
[!warning] 常见误区:配置散落硬编码常量 随部署环境变化的配置应外置;稳定的算法常量并非都要变成环境变量。
工程实践
- 启动时校验全部必填配置。
- 配置项文档化。
- 测试注入假配置。
- 敏感项脱敏日志。
本节总结
- 外置配置
- 校验与优先级
- 密钥分离
自测题
- 为什么配置错误应启动失败?
- 系统属性与环境变量如何选?
参考答案
- 避免带错误配置半运行造成数据事故。
- 按部署方式和应用约定选择 env 或 -D 系统属性;JVM 的 -X/-XX 调优选项不是普通系统属性。记录读取名称、来源与优先级。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| 12-Factor Config | 工程原则 | 配置外置 |