Spring整合MyBatis异常:Mapper与DAO实例化问题排查
问题分析与解决方案
1. 为什么aWattarMapper实例化失败?
MyBatis的@Mapper注解不被Spring的@ComponentScan扫描处理,它需要MyBatis专属的@MapperScan注解来指定Mapper所在的包路径。
单独启动MyElectricity-aWattar时正常,是因为该模块的@SpringBootApplication(或相关配置类)上肯定配置了@MapperScan("de.gombers.electricity.mybatis.awattar"),让MyBatis能扫描并生成Mapper的代理Bean。
但在依赖它的MyElectricity-Sungrow模块中,你只配置了@ComponentScan,没有添加@MapperScan来扫描Mapper所在的de.gombers.electricity.mybatis.awattar包,所以Spring容器里根本没有aWattarMapper的Bean,自然会报找不到的错误。
2. 为什么不在扫描包内的DAO仍被实例化?
你提到DAO位于de.gombers.electricity.mybatis.awattar,而@ComponentScan只指定了de.gombers.electricity.awattar,这两个是平级包,按道理不会被扫描到。出现这种情况的原因大概率是:
aWattarDAO上标注了Spring的组件注解(比如@Repository/@Component),并且MyElectricity-aWattar模块作为依赖,它的Spring配置类被自动导入了。比如该模块的META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中配置了相关的@Configuration类,导致Spring加载了该模块的Bean定义。- 或者你在
MyElectricity-Sungrow的某个类中主动注入了aWattarDAO(比如@Autowired),Spring在处理这个依赖时,会尝试查找并创建该DAO的Bean——如果DAO所在模块的JAR包被引入,且DAO带有Spring组件注解,结合依赖模块的自动配置逻辑,就会被实例化。
修复方案
针对Mapper实例化失败:
在MyElectricity-Sungrow的@SpringBootApplication类上添加@MapperScan,指定Mapper所在的包:
@SpringBootApplication @ComponentScan({"de.gombers.modbus.sungrow", "de.gombers.electricity.awattar"}) @MapperScan("de.gombers.electricity.mybatis.awattar") // 新增这行 public class MyElectricitySungrowApplication { public static void main(String[] args) { SpringApplication.run(MyElectricitySungrowApplication.class, args); } }
针对DAO被意外实例化:
如果不需要在MyElectricity-Sungrow中实例化aWattarDAO:
- 检查
MyElectricity-Sungrow中是否有代码注入了aWattarDAO,如果有,移除不必要的注入。 - 如果
MyElectricity-aWattar是自动配置模块,修改它的自动配置条件,比如添加@ConditionalOnMissingBean或指定特定条件,避免在依赖模块中自动实例化DAO。 - 确保
aWattarDAO上的@Repository注解只在MyElectricity-aWattar模块的配置生效时才被扫描,比如在该模块的@Configuration中用@ComponentScan扫描DAO包,而不是让它被全局扫描。
内容的提问来源于stack exchange,提问作者Ulrich
相关产品推荐
相关产品推荐

