未发布版本 v6.3.0-SNAPSHOT。 本页内容来自 alpha 分支,随时可能变更,不属于任何已发布版本。

commit 49619c6 · 注入于 2026-09-13 12:23 UTC

Skip to content

条件注册

自 v6.2.0 起

@ConditionalOnConfig 注解自 UltiTools-API v6.2.0 起可用。

UltiTools 允许你根据 YAML 配置值来条件性地注册组件。这让服主无需修改代码即可启用或禁用功能。

基本用法

在任意组件类(@Service@CmdExecutor@EventListener)上添加 @ConditionalOnConfig

java
package com.ultikits.docs.conditional;

import com.ultikits.ultitools.abstracts.command.BaseCommandExecutor;
import com.ultikits.ultitools.annotations.ConditionalOnConfig;
import com.ultikits.ultitools.annotations.command.CmdExecutor;
import org.bukkit.command.CommandSender;

@CmdExecutor(alias = {"warp"}, permission = "myplugin.command.warp")
@ConditionalOnConfig(value = "config/config.yml", path = "enableWarp")
public class WarpCommands extends BaseCommandExecutor {
    // Only registered if enableWarp: true in config.yml

    @Override
    protected void handleHelp(CommandSender sender) {
        sender.sendMessage("/warp");
    }
}

对应的 YAML 配置:

yaml
# config/config.yml
enableWarp: true

如果 enableWarpfalse 或缺失,WarpCommands 类将完全不被注册——没有命令注册、没有内存占用、没有副作用。

只有连接器入口点仍然跳过这个条件

标准 @UltiToolsModule 路径把命令类当容器 bean 解析,条件为 false 的类从一开始就不会被构造成 bean,这条路径在 v6.3.0 之前就已经生效。 v6.3.0 起,监听器包扫描路径也会检查这个条件,补上了唯一真实存在的缺口。 只有连接器入口点(PluginManager.register(UltiToolsPlugin))完全不做组件扫描,那里目前还没有任何地方检查这个条件——跟踪于 issue #334

重载漂移报告

@ConditionalOnConfig 只在组件扫描时(插件启动)求值一次。ul reload 会重新读取配置文件,但它本身不会注册或注销任何组件——它只报告发生了什么变化。

v6.3.0 起,漂移消息会说明容器里实际持有什么,而不只是条件现在给出的答案:

[UltiTools-API] @ConditionalOnConfig drift after reload: com.example.MyService (config/config.yml -> myFeature.enabled) now evaluates to disabled, but the component is already registered. @ConditionalOnConfig is evaluated once at component scan; a restart is required to remove the component.

v6.3.0 之前,建议是一句固定文案

消息过去无条件建议"需要重启",哪怕从未构造过任何实例。v6.3.0 起,建议会跟随容器实际持有的状态:已存在且现在禁用会建议重启移除,不存在且现在禁用则无需重启(改看启动日志),不存在且现在启用会建议重启创建,已存在且现在启用同样无需重启。

注解属性

属性类型默认值说明
valueString(必填)相对于插件数据目录的配置文件路径
pathString(必填)点分隔或斜杠分隔的 YAML 键路径
negatebooleanfalse如果为 true,在配置值为 false 时注册(反转逻辑)

示例

条件服务

java
package com.ultikits.docs.conditional;

import com.ultikits.ultitools.annotations.ConditionalOnConfig;
import com.ultikits.ultitools.annotations.Scheduled;
import com.ultikits.ultitools.annotations.Service;

@Service
@ConditionalOnConfig(value = "config/config.yml", path = "economy.enabled")
public class EconomyService {

    @Scheduled(period = 36000, async = true)
    public void distributeTax() {
        // Only runs if economy.enabled: true
    }
}

条件事件监听器

java
package com.ultikits.docs.conditional;

import com.ultikits.ultitools.annotations.ConditionalOnConfig;
import com.ultikits.ultitools.annotations.EventListener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;

@EventListener
@ConditionalOnConfig(value = "config/config.yml", path = "welcomeMessage.enabled")
public class WelcomeListener implements Listener {

    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent event) {
        event.getPlayer().sendMessage("Welcome to the server!");
    }
}

嵌套配置键

使用点号或斜杠来访问嵌套键:

yaml
# config/config.yml
features:
  teleport:
    enabled: true
  pvp:
    enabled: false
java
package com.ultikits.docs.conditional;

import com.ultikits.ultitools.abstracts.command.BaseCommandExecutor;
import com.ultikits.ultitools.annotations.ConditionalOnConfig;
import com.ultikits.ultitools.annotations.command.CmdExecutor;
import org.bukkit.command.CommandSender;

@CmdExecutor(alias = {"tp"}, permission = "myplugin.teleport")
@ConditionalOnConfig(value = "config/config.yml", path = "features.teleport.enabled")
public class TeleportCommands extends BaseCommandExecutor {

    @Override
    protected void handleHelp(CommandSender sender) {
        sender.sendMessage("/tp");
    }
}

反转逻辑(negate)

使用 negate = true 在配置值为 false 时注册组件:

java
package com.ultikits.docs.conditional;

import com.ultikits.ultitools.annotations.ConditionalOnConfig;
import com.ultikits.ultitools.annotations.Service;

@Service
@ConditionalOnConfig(value = "config/config.yml", path = "maintenance", negate = true)
public class NormalModeService {
    // Only active when maintenance: false (or missing)
}

完整示例

通过配置控制可选功能的插件:

yaml
# config/config.yml
features:
  home: true
  warp: true
  economy: false
  welcome: true
java
package com.ultikits.docs.conditional;

import com.ultikits.ultitools.abstracts.UltiToolsPlugin;
import com.ultikits.ultitools.annotations.UltiToolsModule;

@UltiToolsModule(scanBasePackages = {"com.ultikits.docs.conditional"})
public class MyPlugin extends UltiToolsPlugin {
    @Override
    public boolean registerSelf() { return true; }

    @Override
    public void unregisterSelf() { }
}
java
@CmdExecutor(alias = {"home"}, permission = "myplugin.home")
@ConditionalOnConfig(value = "config/config.yml", path = "features.home")
public class HomeCommands extends BaseCommandExecutor {
    // 已注册(features.home = true)

    @Override
    protected void handleHelp(CommandSender sender) { }
}

@CmdExecutor(alias = {"warp"}, permission = "myplugin.warp")
@ConditionalOnConfig(value = "config/config.yml", path = "features.warp")
public class WarpCommands extends BaseCommandExecutor {
    // 已注册(features.warp = true)

    @Override
    protected void handleHelp(CommandSender sender) { }
}

@Service
@ConditionalOnConfig(value = "config/config.yml", path = "features.economy")
public class EconomyService {
    // 未注册(features.economy = false)
}

@EventListener
@ConditionalOnConfig(value = "config/config.yml", path = "features.welcome")
public class WelcomeListener implements Listener {
    // 已注册(features.welcome = true)
}

v6.2.0 之前

没有 @ConditionalOnConfig 时,开发者需要在 registerSelf() 中手动检查配置值,并使用 if 语句条件性地注册组件。注解方式更简洁,消除了样板代码。

贡献者

暂无相关贡献者

基于 MIT 许可发布