自定义插件NovEcon2与RealBanks2启动时因循环依赖无法加载求助
解决NovEcon2与RealBanks2的循环依赖加载问题
问题背景
我开发了两款Spigot插件:
- NovEcon2:经济插件,
plugin.yml中设置Vault和RealBanks2为软依赖(softdepend) - RealBanks2:银行插件,依赖Vault(硬依赖)
当NovEcon2配置文件中configlet-bool设为true时,RealBanks2会调用NovEcon2的内部API,但此时出现循环依赖导致两款插件都加载失败:
- NovEcon2启动时检测不到RealBanks2,直接被禁用
- RealBanks2启动时,因为Vault还未找到可用的经济插件(NovEcon2已被禁用),也被禁用
服务器启动日志片段:
[18:31:35 INFO]: [Vault] Enabling Vault v1.7.3-b131 [18:31:35 INFO]: [Vault] [Permission] SuperPermissions loaded as backup permission system. [18:31:35 INFO]: [Vault] Enabled Version 1.7.3-b131 [18:31:35 INFO]: [NovEcon2] Enabling NovEcon2 v1.0.0 [18:31:35 ERROR]: [NovEcon2] - Disabled due to no RealBanks dependency found! [18:31:35 INFO]: [NovEcon2] Disabling NovEcon2 v1.0.0 .... [18:31:36 INFO]: [RealBanks2] Enabling RealBanks2 v2.0.0 [18:31:36 ERROR]: [RealBanks2] - Disabled due to no Vault dependency found! [18:31:36 INFO]: [RealBanks2] Disabling RealBanks2 v2.0.0
尝试过调整plugin.yml的依赖顺序、添加loadbefore,以及考虑开发桥接插件,但均未解决问题,寻求可行方案。
可行解决方案
方案1:延迟依赖检测与API初始化
把依赖检测和API调用从插件onEnable()阶段推迟,避免启动时的强依赖冲突:
- NovEcon2端修改:
- 删掉
onEnable()里对RealBanks2的强制检测逻辑,改成软检查——启动时不直接禁用插件,只打警告日志,同时监听PluginEnableEvent,等RealBanks2加载完成后再初始化交互模块。 - 针对
configlet-bool配置:如果为true,等RealBanks2加载后再注册供它调用的API;如果为false,直接跳过相关逻辑。
- 删掉
- RealBanks2端修改:
- 删掉
onEnable()里对NovEcon2 API的立即调用,改成监听PluginEnableEvent,等NovEcon2加载完成后再尝试获取并初始化API;如果NovEcon2没加载或配置未开启,只禁用相关功能,不要直接禁用整个插件。 - 调整Vault依赖逻辑:不要在
onEnable()里因没找到经济插件就禁用,改成监听Vault的EconomyChangeEvent,等有经济插件注册后再初始化银行核心功能;如果始终没经济插件再禁用。
- 删掉
方案2:重构API依赖方向
反转调用逻辑,让NovEcon2主动向RealBanks2注册功能,而非RealBanks2主动拉取API:
- 在RealBanks2里定义一个公共的注册接口(比如
EconomyFeatureRegistry),允许外部插件注册经济相关功能实现。 - NovEcon2启动完成后(或检测到RealBanks2加载后),如果
configlet-bool为true,就通过这个注册接口把自身功能注册到RealBanks2中。 - 这样RealBanks2无需主动依赖NovEcon2的API,仅提供注册入口,从根源消除循环依赖触发条件。
方案3:拆分功能到独立模块
如果交互逻辑复杂,把共享API或交互逻辑拆成独立的基础插件:
- 新建一个插件(比如
NovEconBridge)作为中间层,NovEcon2和RealBanks2都软依赖这个桥接插件。 - 桥接插件只负责定义交互的标准接口,NovEcon2实现接口并注册到桥接插件,RealBanks2从桥接插件获取实现实例。
- 这种方式能彻底解耦两款插件的直接依赖,同时避免循环问题(桥接插件不依赖任何一方)。
方案4:调整加载优先级与依赖声明
通过plugin.yml配置配合启动阶段软检查:
- 在NovEcon2的
plugin.yml中添加loadbefore: [RealBanks2],确保NovEcon2先加载。 - NovEcon2的
onEnable()里,先完成Vault的经济注册逻辑,再处理与RealBanks2的交互——即使RealBanks2没加载,也不影响核心经济功能。 - RealBanks2的
onEnable()里,先检查Vault是否有可用经济插件(此时NovEcon2已完成注册),再尝试加载与NovEcon2交互的功能;如果NovEcon2没加载,仅禁用相关功能而非整个插件。
内容的提问来源于stack exchange,提问作者LinuxSquare
相关产品推荐
相关产品推荐

