Apache Commons Configuration:NodeTreeWalker使用示例求助
使用NodeTreeWalker遍历Commons分层配置的实践经验
下面是实际实现的代码示例和关键说明,帮你快速上手NodeTreeWalker的walkDFS和walkBFS方法:
1. 依赖准备
确保项目引入Commons Configuration 2.x版本(以Maven为例):
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-configuration2</artifactId> <version>2.8.0</version> </dependency>
2. 初始化分层配置
先构造一个示例分层配置,或者从XML/YAML等文件加载真实配置:
// 初始化基础分层配置 HierarchicalConfiguration<ImmutableNode> config = new BaseHierarchicalConfiguration(); config.addProperty("app.name", "DemoApp"); config.addProperty("app.server.host", "localhost"); config.addProperty("app.server.port", 8080); config.addProperty("app.log.level", "INFO"); config.addProperty("app.log.file", "/var/log/app.log"); // 带索引的列表节点示例 config.addProperty("app.users[0].name", "Alice"); config.addProperty("app.users[0].role", "admin"); config.addProperty("app.users[1].name", "Bob"); config.addProperty("app.users[1].role", "user");
3. 核心遍历实现
3.1 深度优先遍历(DFS)
使用walkDFS,通过NodeVisitor的两个回调方法处理节点的前序和后序访问:
// 获取配置根节点 ImmutableNode rootNode = config.getNodeModel().getRootNode(); NodeTreeWalker walker = new NodeTreeWalker(); // DFS遍历实现 walker.walkDFS(rootNode, new NodeVisitor<ImmutableNode>() { @Override public void visitBeforeChildren(ImmutableNode node, NodeHandler<ImmutableNode> handler) { // 前序访问:先处理当前节点,再遍历子节点 String nodePath = handler.nodeKey(node); Object nodeValue = node.getValue(); // 跳过无实际路径的根节点 if (!nodePath.isEmpty()) { System.out.printf("DFS 前序: 路径=%s, 值=%s%n", nodePath, nodeValue); } } @Override public void visitAfterChildren(ImmutableNode node, NodeHandler<ImmutableNode> handler) { // 后序访问:遍历完所有子节点后处理当前节点 String nodePath = handler.nodeKey(node); if (!nodePath.isEmpty()) { System.out.printf("DFS 后序: 路径=%s%n", nodePath); } } });
3.2 广度优先遍历(BFS)
使用walkBFS,通常只需要前序访问回调即可:
// BFS遍历实现 walker.walkBFS(rootNode, new NodeVisitor<ImmutableNode>() { @Override public void visitBeforeChildren(ImmutableNode node, NodeHandler<ImmutableNode> handler) { String nodePath = handler.nodeKey(node); Object nodeValue = node.getValue(); if (!nodePath.isEmpty()) { System.out.printf("BFS 访问: 路径=%s, 值=%s%n", nodePath, nodeValue); } } @Override public void visitAfterChildren(ImmutableNode node, NodeHandler<ImmutableNode> handler) { // BFS场景下后序访问一般无需求,留空即可 } });
关键说明
- NodeVisitor回调:
visitBeforeChildren是节点被访问的第一时机(前序),visitAfterChildren是所有子节点遍历完成后触发(后序,主要用于DFS) - NodeHandler工具:
handler.nodeKey(node)可以获取节点的完整配置路径(比如app.server.host),方便定位节点位置 - 节点值处理:
node.getValue()返回节点的原始值,列表节点的子节点会带有索引路径(比如app.users[0].name) - 配置加载适配:如果是从XML/YAML文件加载的配置(比如
XMLConfiguration),同样可以通过getNodeModel().getRootNode()获取根节点,遍历逻辑完全一致
注意事项
- 避免在遍历大型深层配置时使用DFS,可能触发栈溢出;BFS更适合宽而浅的配置结构
ImmutableNode是不可变对象,遍历过程中无法修改节点;若需修改配置,需使用MutableNode和对应的可修改配置类(比如BaseHierarchicalConfiguration本身支持修改)
内容的提问来源于stack exchange,提问作者David H
相关产品推荐
相关产品推荐

