Class Config
职责边界:本类只负责把 Schema 中定义的
ConfigKey 变成一个可靠、类型安全、隔离良好的 Runtime Value Store。
不包含 YAML 解析、文件读写、同步、命令、热加载——那些分别属于
ConfigLoader、ConfigWriter、ConfigSynchronizer 与命令层。
Config = Runtime Value Store ← 本类 ConfigLoader = YAML → Runtime ConfigWriter = Runtime → YAML ConfigRegistry= Schema
关键不变量:
- 不暴露可变值引用:
get与set都经ConfigCodec.copy(Object), 外部无法通过config.get(listKey).add(...)绕过校验直接改内部状态; set失败不污染旧值:先解析校验,全部通过后才写入;load原子替换:全部转换校验成功后才一次性替换状态,失败时保持原状态;- Key 归属校验:
ConfigKey以对象身份标识,使用其它 Registry 的 Key 会抛异常; - 不修改 ConfigKey:Schema 不可变,运行时状态可变,二者严格分离;
set不落盘:持久化由 Phase 5 的 Writer 负责,避免批量修改产生多次 I/O。
并发:状态是不可变快照,持有在 AtomicReference 中。
get 无锁读取;set/reset/load 用 CAS 替换整份状态,
因此读操作不会看到"半加载"状态。
- Since:
- 0.6.12
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionboolean判断用户配置中是否显式存在该字段供测试与调试使用的值快照描述<T> T读取生效值boolean判断当前值是否来源于默认值voidload(ConfigDocument document) 用一份已解析的配置文档原子替换运行时状态void用一份已解析的配置文档原子替换运行时状态<T> void恢复为默认值<T> void设置运行时值intsize()snapshot()取当前状态的不可变快照
-
Constructor Details
-
Config
构造运行时值存储- Parameters:
registry- Schema 注册中心
-
-
Method Details
-
get
读取生效值字段缺失时返回默认值(不是 null)。可变类型返回副本, 修改返回值不会影响内部状态。
- Type Parameters:
T- 值类型- Parameters:
key- 配置项- Returns:
- 生效值副本
- Throws:
ConfigValidationException- key 不属于本 Runtime 的 Registry
-
contains
判断用户配置中是否显式存在该字段与
get(ConfigKey)语义严格区分:缺失字段的get返回默认值, 但contains返回 false。- Parameters:
key- 配置项- Returns:
- true 表示值来源于用户配置
-
isDefault
判断当前值是否来源于默认值不是简单的
value.equals(defaultValue): 用户显式写了与默认值相同的值,仍然属于USER,本方法返回 false。- Parameters:
key- 配置项- Returns:
- true 表示值来源于默认值
-
set
设置运行时值流程:归属校验 → codec 解析(类型一致性)→ validator → copy → 写入。 任何一步失败都抛
ConfigValidationException,且旧值保持不变。不会自动落盘——持久化由调用方显式触发(未来命令层
set → save)。- Type Parameters:
T- 值类型- Parameters:
key- 配置项value- 新值- Throws:
ConfigValidationException- 类型不符或校验不通过
-
reset
恢复为默认值结果与"用户配置中不存在该字段"一致:
get返回默认值副本,contains为 false,isDefault为 true。 每次 reset 都经 codec 复制,因此多次 reset 得到的可变默认值互不影响。- Type Parameters:
T- 值类型- Parameters:
key- 配置项
-
load
用一份已解析的配置文档原子替换运行时状态YAML 解析不在这里:由
ConfigFileReader负责把文件解析成Map<String, Object>(或ConfigDocument)后调用本方法。原子性:先对全部已注册的 Key 完成"取值 → codec 解析 → validator", 全部成功后才一次性替换状态;任何一项失败都会抛异常并保持 load 之前的状态, 绝不会出现"一半新一半旧"。
缺失即默认:文档中没有的字段不算错误,记为
ConfigValueSource.DEFAULT;只有"存在但类型错误 / 校验失败"才是配置错误。- Parameters:
document- 已解析的配置文档,可为 null(等价于空文档)- Throws:
ConfigValidationException- 存在类型错误或校验失败的字段
-
load
用一份已解析的配置文档原子替换运行时状态与
load(Map)等价,但走的是统一的路径解析入口(ConfigDocument), 避免出现第二套路径遍历逻辑。- Parameters:
document- 已解析的配置文档,可为 null(等价于空文档)- Throws:
ConfigValidationException- 存在类型错误或校验失败的字段
-
size
public int size()- Returns:
- 已注册配置项数量
-
snapshot
取当前状态的不可变快照供 Writer 等长操作使用:它们只处理快照,因此不会被并发的
set/load影响, 也不会长时间持锁。- Returns:
- 运行时快照
-
describeEntries
供测试与调试使用的值快照描述- Returns:
- 形如
websocket_server.port=8080(USER)的列表
-