背景
工程中集成了ShardingSphere,集成之后发现无法启动,报错信息如下:
解决
报错的根本原因是:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.apache.shardingsphere.infra.config.mode.ModeConfiguration' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
典型的org.springframework.beans.factory.NoSuchBeanDefinitionException
问题:更具体是Spring找不到org.apache.shardingsphere.infra.config.mode.ModeConfiguration
,那么首先看下工程中是否包含这个类。
-
很明显工程中存在这个类,但是比较奇怪,这是一个被final修饰的类,但是没有任何注解,Spring报的错误是在autowire的时候找不到类,因此怀疑是没有加注解引起的。
-
执行mvn命令分析依赖
mvn dependency:tree > dependency.txt
分析依赖结果:该依赖为common工程的依赖。查看common工程的依赖:
这里排除了一个shardingsphere-infra-common的依赖,引入了另外一个依赖。经过查证这个新的依赖项是一个自己构建的版本。那么下一步就是查看这个工程的代码。
- 从仓库中clone下来代码,shardingsphere的代码很多,这里重点关注的是common,执行如下maven命令构建指定子模块。
mvn install -pl shardingsphere-infra -am
其中pl后面是指定子模块,-am表示构建所列模块的指定模块。
-
使用idea子模块,尝试在
ModeConfiguration
加上注解,直接失败,因此肯定不是在源码上加上注解就能完成的,但是在实际运行过程中有需要这个配置类,那么肯定有地方创建了这个对象,并且作为一个bean注入到容器中。 -
在
ShardingSphereAutoConfiguration
中看到了这个类的注入,代码如下:
@Bean
public ModeConfiguration modeConfiguration() {
return null == this.props.getMode() ? null : (new ModeConfigurationYamlSwapper()).swapToObject(this.props.getMode());
}
很明显,需要属性中有一个mode的配置,然后根据mode属性创建ModeConfiguration。
-
需要查一下ModeConfiguration支持哪几种类型。详细的可以参考sharding模式
-
最终解决方案在配置文件中新增:
spring.shardingsphere.mode.type=Memory
小结
针对NoSuchBeanDefinitionException
典型的错误,主要就是要弄清楚报错的这个类是否被创建,若没有被创建,需要找到具体的原因,然后在做针对性的修复。