Config 配置类指南
本文档将指导您如何基于 Nukkit-MOT 框架开发规范创建规范的配置管理系统,涵盖基础配置读取、嵌套对象处理、动态保存等核心功能。
配置文件结构
建议采用 YAML 格式组织配置文件,典型结构如下:
config.yml
this-is-a-key: Hello! Config! # 字符串类型配置
another-key: true # 布尔值配置
object-key: # 对象类型配置
enabled: false
subKey1: nukkit
subKey2: 2023
array-key: # 数组类型配置
- first element
- second element
- third element
📁ExamplePlugin-Maven
📁lib
📁src
📁main
📁java
📁resources
📄config.yml
📁target
配置类实现
基础配置类
public class ExampleConfig {
private final Config config;
// 使用 Lombok 自动生成 Getter
@Getter private String aKey;
@Getter private boolean anotherKey;
@Getter private ArrayList<String> arrayKey;
public ExampleConfig() {
// 确保配置文件存在(自动创建空配置)
ExamplePlugin.getInstance().saveResource("config.yml");
// 初始化配置对象(带默认值)
config = new Config(
new File(ExamplePlugin.getInstance().getDataFolder(), "config.yml"),
Config.YAML,
new ConfigSection(new LinkedHashMap<>() {{
// 默认值配置区
put("this-is-a-key", "Hello! Config!");
put("another-key", true);
// 嵌套对象默认值
put("object-key", new LinkedHashMap<String, Object>() {{
put("enabled", false);
put("subKey1", "nukkit");
put("subKey2", 2023);
}});
// 数组默认值
put("array-key", Arrays.asList(
"first element",
"second element",
"third element"
));
}})
);
// 加载配置到内存
setAKey(config.getString("this-is-a-key"));
setAnotherKey(config.getBoolean("another-key"));
setArrayKey((ArrayList<String>) config.getStringList("array-key"));
}
}
嵌套对象处理
// 在 ExampleConfig 类中定义嵌套配置对象
public class KeyObject {
private final ConfigSection configSection;
@Getter private boolean enabled;
@Getter private String subKey1;
@Getter private Integer subKey2;
public KeyObject() {
// 获取对象配置区
this.configSection = config.getSection("object-key");
// 带默认值的读取方式
this.enabled = configSection.getBoolean("enabled", false);
this.subKey1 = configSection.getString("subKey1", "nukkit");
this.subKey2 = configSection.getInt("subKey2", 2023);
}
// 支持链式调用的设置方法
public KeyObject setEnabled(boolean value) {
enabled = value;
configSection.set("enabled", enabled);
return this;
}
}
配置动态保存
// 主配置保存方法
public void save() {
config.set("this-is-a-key", aKey);
config.set("another-key", anotherKey);
config.set("array-key", arrayKey);
config.save();
}
// 嵌套对象保存方法
public ExampleConfig save() {
configSection.set("enabled", enabled);
configSection.set("subKey1", subKey1);
configSection.set("subKey2", subKey2);
config.save();
return parent;
}
最佳实践
- 默认值保障:在构造函数中始终提供默认值配置,防止配置文件损坏
- 类型安全:使用
getBoolean()/getInt()等类型化方法替代通用get() - 配置隔离:对嵌套对象使用独立的配置类进行管理
- 内存缓存:首次加载时将配置存入内存字段,避免频繁读取文件
- 有序存储:使用
LinkedHashMap保持配置项的写入顺序 - 链式调用:set 方法返回 this 简化代码
配置热重载
通过监听服务器重载命令实现配置热更新:
// 在插件主类注册事件
@EventHandler
public void onReload(ServerCommandEvent event) {
if (event.getCommand().equals("reload example")) {
this.config = new ExampleConfig();// 重新实例化即可
getLogger().info("配置重载完成!");
}
}
备注
热重载可能影响正在运行的业务逻辑
调试技巧
使用 config.getRootSection().toString() 可快速输出当前加载的完整配置:
getLogger().info("当前配置状态:\n" + config.getRootSection().toString());
使用 eu.okaeri.configs(内置依赖)
Nukkit-MOT 内置了 okaeri-configs(坐标 okaeri-configs-yaml-snakeyaml),服务端内部使用它来管理 nukkit-mot.yml。插件可以直接使用,运行期无需额外打包依赖。相比传统 Config API 的优势:
- 基于 POJO:字段即 schema,避免散落各处的字符串 key。
- 强类型:直接反序列化为真实 Java 类型,包括嵌套对象与泛型
List/Map。 - 注解支持:
@Comment、@Header、@CustomKey可在生成的 YAML 中自动写入注释与自定义键名。 - 孤立键清理:
removeOrphans(true)在 schema 演进时自动清掉旧版本残留的无用键。
备注
请在构建里以 <scope>provided</scope>(Maven)或 compileOnly(Gradle)的方式声明 okaeri-configs-yaml-snakeyaml,服务端运行时已经提供该依赖。
定义配置类
import eu.okaeri.configs.OkaeriConfig;
import eu.okaeri.configs.annotation.Comment;
import eu.okaeri.configs.annotation.CustomKey;
import eu.okaeri.configs.annotation.Header;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.util.ArrayList;
import java.util.List;
@Getter
@Setter
@Accessors(fluent = true)
@Header("########################################")
@Header("ExamplePlugin Configuration")
@Header("########################################")
public class ExampleConfig extends OkaeriConfig {
@Comment("玩家加入时显示的欢迎语")
@CustomKey("welcome-message")
private String welcomeMessage = "Hello! Config!";
@Comment("是否启用该功能")
private boolean enabled = true;
@Comment({"", "嵌套设置块"})
@CustomKey("feature-settings")
private FeatureSettings featureSettings = new FeatureSettings();
@Comment("生效的世界列表")
private List<String> worlds = new ArrayList<>();
}
嵌套分类只需要再继承一次 OkaeriConfig 即可:
@Getter
@Setter
@Accessors(fluent = true)
public class FeatureSettings extends OkaeriConfig {
@Comment("冷却时间(tick)")
private int cooldown = 20;
@CustomKey("max-uses")
private int maxUses = 10;
}
加载与保存
import eu.okaeri.configs.ConfigManager;
import eu.okaeri.configs.yaml.snakeyaml.YamlSnakeYamlConfigurer;
public class ExamplePlugin extends PluginBase {
private ExampleConfig config;
@Override
public void onEnable() {
java.io.File file = new java.io.File(getDataFolder(), "config.yml");
getDataFolder().mkdirs();
this.config = ConfigManager.create(ExampleConfig.class, it -> {
it.configure(opt -> {
opt.configurer(new YamlSnakeYamlConfigurer());
opt.bindFile(file);
opt.removeOrphans(true); // 自动剔除类中已删除的旧 key
});
it.saveDefaults(); // 文件不存在时写入默认值
it.load(true); // 加载后立即回写一次,规范化注释与顺序
});
getLogger().info(config.welcomeMessage());
}
public void updateAndSave() {
config.enabled(false);
config.featureSettings().cooldown(40);
config.save();
}
}
热重载
public void reload() {
this.config.load(); // 直接从绑定文件重新读取
}
何时使用哪一个
OkaeriConfig:schema 固定、需要注释/嵌套分类、运行时较少动态修改。Config:动态/用户自定义 key、运行期结构不固定,或需要非 YAML 格式(PROPERTIES、TXT、TOML、DETECT自动识别)。
提示
Nukkit-MOT 自身就用 OkaeriConfig 管理 nukkit-mot.yml,用 Config 管理 server.properties。可参考源码 ServerConfig.java。