两个插件内用Spring扫描不同版本依赖中的bean时出错
-
前提:
第一个插件通过gradle依赖得到了v1版本的
hundun.quizgame.core包
,最后打出的插件jar的中有:GameService通过@Autowired注入成员
hundun.quizgame.core.model.match.strategy.MatchStrategyFactory
第二个插件通过gradle依赖得到了v2版本的
hundun.quizgame.core包
,最后打出的插件jar的中有:GameService通过@Autowired注入成员
hundun.quizgame.core.model.domain.match.strategy.MatchStrategyFactory
(路径比v1多了domain)问题:
若两个插件分别放入mirai-console,均正常工作。
若两个插件同时放入mirai-console, 第二个插件onEnable成功,第一个插件onEnable时报错,报错内容表明它试图寻找v2版本的包路径的MatchStrategyFactory的bean。
// 这里能看出是第一个插件启动时的报错 E/hundun.zacafleetbot.router: onEnable error: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'amiya': Unsatisfied dependency expressed through field 'quizHandler'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'quizHandler': Unsatisfied dependency expressed through field 'quizService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'gameService': Unsatisfied dependency expressed through field 'matchStrategyFactory'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'hundun.quizgame.core.model.domain.match.strategy.MatchStrategyFactory' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
分析
@ryoii 在 插件里Spring的AnnotationConfigApplicationContext扫描不到bean 中说:
注意,这个 SpringContext 是否能扫描到插件之外的 Bean 取决与 Mirai Console 的实现
和这应该不是一回事吧?这里的预期行为是第一个插件使用v1路径的MatchStrategyFactory在插件内找bean,不关心是否能从插件外扫描到v2路径的MatchStrategyFactory。
这和issue:调整插件类加载策略: 优先加载自己 JAR, 再从全局搜索; 让插件 JAR 携带除 mirai 外所有运行时依赖 是同一个问题吗?
-
看起来确实是一个插件scan公共包时,会扫描到并得到另一个插件内的公共包的bean。
暂时不打算让插件脱离Spring,折中一下,准备把公共包改成脱离Spring。