springboot不扫描@repository的问题及解决
作者:Smaksze
springboot不扫描@repository问题
问题
单独使用@repository注解注dao层,而且不使用@mapperscan扫描时,启动项目会报错:
Field xxxxMapper in com.sms.shiro.service.impl.xxxxServiceImpl required a bean of type ‘com.sms.shiro.mapper.xxxxMapper’ that could not be found.
一.@mapper和@repository的区别
1.@mapper是mybatis的注解,@repository是spring家族的注解。
2.使用@mapper注解时,spring并不认识,@autowired注入到service里的mapper会爆红。
二.回到问题中来
明明springboot里的ComponentScan扫描了启动器包下的所有含注解的组件,那为什么却找不到@repository的组件?
原因:
造成这个问题的原因是因为springboot在扫描时候自动过滤掉了接口和抽象类,所以@repository修饰的mapper接口并不能称为一个bean,自然也就无法注入到service中。
三.解决方式
第一种: 不使用@repository,在mapper层接口直接使用@mapper,但如果项目工程较大的话就会很麻烦。
第二种: 如果想使用@repository,因为springboot无法扫描到mapper接口,则在启动器上使用@mapperscan扫描所有mapper接口的包,如:@MapperScan("com.sms.shiro.*.mapper")
第三种: 其实使用@mapperscan注解扫描mapper接口后,mapper接口就不需要@repository和@mapper去注册bean了,但如果想项目结构比较明了,在使用了@mapperscan扫描后,@repository和@mapper都可使用,都不会报错了,但是使用@repository会解决在service中@autowired mapper爆红的问题。
SpringBoot关于@Mapper和@Repository的一些疑问
@Mapper 是 Mybatis 的注解,和 Spring 没有关系,@Repository 是 Spring 的注解,用于声明一个 Bean。
@Mapper
Mybatis 需要找到对应的 mapper,在编译的时候动态生成代理类,才能实现对数据库的一系列操作,所以我们需要在接口上添加 @Mapper 注解。
例如(这里只是为了演示并且sql不复杂,所以这里使用注解的方式来编写sql语句):
@Mapper public interface UserMapper { @Select("select * from user where id = #{id}") User getById(Integer id); @Select("select * from user") List<User> getAll(); }
编写测试方法,可以发现加了自动装配注解的userMapper会出现报错(并不影响代码正常运行),这是因为@Mapper是Mybatis中的注解,我们没有显示的标明UserMapper是spring中的一个Bean,idea此时会认为在运行时找不到实例注入,所以会提示错误
虽然这个报错并不影响代码的正常运行,但是看着很不舒服,我们可以@Repository注解(也可以使用@Componet,只要注明这是一个bean就可以)来显示的说明UserMapper是一个bean
@Repository
@Repository 是spring提供的一个注解,用于声明 dao 层的 bean,如果我们要真正地使用 @Repository 来进行开发,那么我们需要手动实现UserMapperImpl,也就是说手写 JDBC代码!!!
@Repository public class UserMapperImpl implements UserMapper{ @Override public User getById(Integer id){ // 装载Mysql驱动 // 获取连接 // 创建Statement // 构建SQL语句 // 执行SQL返回结果 } }
@MapperScan(“com.xxx.xxx”)
如果我们不使用@Mapper注解,还有另一种方式让Mybatis找到mapper接口,那就是 @MapperScan 注解,可以在启动类上添加该注解,自动扫描包路径下的所有mapper接口。
@SpringBootApplication @MapperScan("com.example.springboot_mybatis.mapper") public class SpringbootMybatisApplication { public static void main(String[] args) { SpringApplication.run(SpringbootMybatisApplication.class, args); } }
使用@MapperScan注解之后,就不需要在mapper接口上添加任何注解了!!
心得:
总的来说,@Mapper 和 @MapperScan 这两个必须有一个,否则就会出错!
@Repository 可有可无,对程序正常运行没什么影响,但是可以消除idea报错的问题
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。