背景:前几天有个需求,把一个大项目里面几个模块独立出来。本来不是什么大事,毕竟接口都是现成的。原项目是用spring+hibernate框架做的,独立部分接口比较简单,我寻思整合一个ssm的框架,用mybatisPlus的条件构造器代替原来用JdbcTemplate写的sql。
springBoot的配置很简单,无非就是yml里配置端口、连接池、日志,pom文件引入依赖等等。在这里提下,maven的版本选低版本的,我一般用3.3.9,最新的3.6版本会有问题,啥问题忘了。但是这玩意不好找,我贴个连接:
链接: https://pan.baidu.com/s/1oIJnsPSMCoKP2L30lAkhQg 提取码: cvkg
另外maven的setting配置里面有个镜像,改成阿里云的下载jar会快很多,怎么改网上一堆
至此,乞丐版的ssm框架基本就完事了,为什么是乞丐版呢,因为后面还会配置lombok、P6SpyLogger、分页插件、swagger一堆玩意。
当把原项目的代码撸过来之后,问题就来了,主要是对启动类里面@MapperScan和@ComponentScan两个注解理解不深刻导致的。先贴个项目结构图:代码是代码生成器生成的,每一张表都有对应的controller(控制器)、service(服务层)、serviceImpl(service实现类)、dao(持久层)、mapper.xml(sql)、entity(实体)
为了更规范,每一个方法都在service有相应的接口,然后在serviceImpl实现,serviceImpl类名上加了@service注解用来注入。
于是遇到了第一个问题,启动时报错:
org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'userService' for bean class [com.example.demo.service.UserService] conflicts with existing, non-compatible bean definition of same name and class [com.example.demo.service.impl.ZCUserServiceImpl]
大概就是装配service时冲突,重名了。找到好多教程试了也不行,最后问题定位在启动类的注解上。查了资料这两个注解的用法:@ComponentScan是组件扫描注解,用来扫描@Controller @Service @Repository这类,@MapperScan 是扫描mapper类的注解,在这里就是dao层。是的我写反了:
我用@MappperScan扫描全包,这玩意按理说也可以扫,但是它比较蠢,我理解它会在扫描service类的时候装配一次,扫描serviceImpl里面@service注解的时候也装配一次,而一般@service注解的value值会写成接口类的首字母小写形式,两个就重名了。
所以呢,解决办法有两个:1、避免@MapperScan同时扫描service和serviceImpl包,所以一般只用于扫描dao;2、@service注解的value值不要与service类同名。
这里插叙一下,一开始机智如我并没有总结出上面另两个结论,以为是@ComponentScan的问题,于是把它注掉了,并选择了第2种方案。众所周知,启动失败。。
Description:
Field zcUserService in com.example.demo.controller.InterAPIController required a single bean, but 2 were found:
- serService: defined in file [E:\workSpace\demo--\target\classes\com\example\demo\service\impl\ZCUserServiceImpl.class]
- userService: defined in file [E:\workSpace\demo--\target\classes\com\example\demo\service\UserService.class]
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
但是报错不一样了,多少还是有点欣慰的。大概翻译下:
Spring:啊这!这波是强人所难!
为什么spring这么说呢,由于两次装配的bean不同,@Autowirte注入service也注入了两个,正如日志所说,要定义一个Primary,也就是主要。但是我们直接选择上面第1种方案就不会有这样的问题了。
综上所述,@MapperScan扫描dao,@ComponentScan扫描全包
来源:CSDN
作者:老人与猹
链接:https://blog.csdn.net/qq_42043053/article/details/104678149