@MapperScan 和 @Mapper 源码走读
创始人
2024-02-06 11:19:32
0

一.从开发中遇到的问题开始

问题描述 : 在一个springboot+mybatis的项目中,在dao也就是Mapper接口上配置了@Mapper注解,其他同事在启动类还配置了@MapperScan注解(包扫描没有配全面),进行批量指定所生成的Mapper接口动态代理接口类,所以开始的时候没有在@MapperScan直接我新建的dao包,就报错,但是有@Mapper注解。

No qualifying bean of type 'com.xxx.mapper.xxxMapper' 
available: expected at least 1 bean which qualifies as autowire 
candidate. Dependency annotations:{@org.springframework.beans
.factory.annotation.Autowired(required=true)}

1、只使用@Mapper注解,不使用@MapperScan注解。会扫描@Mapper注解所在接口,生成动态代理类,注入到Spring容器中。

2、只使用@MapperScan注解,不使用@Mapper注解。会扫描@MapperScan注解配置的包下面的接口生成动态代理类,注入到Spring容器中。

3、@Mapper、@MapperScan注解都使用,@Mapper接口,在@MapperScan注解中有配置包路径,那么可以正常使用。

4、@Mapper、@MapperScan注解都使用,@Mapper接口,在@MapperScan注解中没有配置包路径,那么会报错,解决办法,就是在@MapperScan注解中配置正确路径下的包即可。

二.@Mapper、@MapperScan注解解释

@Mapperscan:标注在 springboot 的启动类上面,配置 basePackages 属性,可以去扫描指定路径下的接口扫描为 Mapper 接口。

@Mapper:标注在接口上,表明这是一个 Mapper 接口。

工作原理:两者都使普通接口转为 mapper 接口,也即是把接口的beanClass设置为mapperFactoryBean

三.源码分析

1.@MapperScan注解扫描分析

可以发现 @Mapperscan注解类中包含有注解@Import(MapperScannerRegistrar.class)
在这里插入图片描述

MapperScannerRegistrar实现了ImportBeanDefinitionRegistrar ,那么在启动时spring容器会调用并执行 registerBeanDefinitions() 方法,扫描对应路径上(@MapperScan注解上带的basepackages)的类扫描到spring容器中.

在这个方法中重点看这行代码:
在这里插入图片描述

代码中会实例化 MapperScannerConfigurer,这个类实现了BeanDefinitionRegistryPostProcessor,会容器启动时调用postProcessBeanDefinitionRegistry() 方法,在这方法中设置了接口的 beanClass 。
在这里插入图片描述

ClassPathMapperScanner 重写了doScan方法,主要是扫描路径,并将扫描的信息转为beanDefinition,设置其为MapperFactoryBean,最终将扫描好并封装为MapperFactoryBean的类加入到ioc容器中
在这里插入图片描述

mapperFactoryBean重写了getObejct()方法。
在这里插入图片描述

跟踪 getObject() 方法,发现最终实例化接口的代码如下:
在这里插入图片描述

也即是我们写 mapper 接口,然后 mybatis 为我们生成一个 MapperProxy 对象去实现 mapper 接口。

1.1@MapperSca总结

@MapperScan 实际做的事情:
1.扫描指定路径,并将路径下的信息记录为BeanDefinition;
2.将获取的BeanDefinition,设置为MapperFactoryBean,注入IOC;

2.@Mapper注解扫描分析

@Mapper 注解是在 mybatis加载时候起作用的,在 MybatisAutoConfiguration 中:

如果当前IOC容器没有MapperFactoryBean.class, MapperScannerConfigurer.class这两个bean,则会执行如下代码
在这里插入图片描述
由该类的头部注解可知,在 spring 上下文中没有 MapperScannerConfigurer 实例时候会进行对@Mapper注解类的初始化。由此可知 @Mapper和@Mapperscan只有一个起作用,而 @Mapperscan 优先级较高。因此当 @Mapperscan 不存在时候,MybatisAutoConfiguration 该类的头部注解@import,会实例化 AutoConfiguredMapperScannerRegistrar ,这个类 会调用registerBeanDefinitions方法,将MapperScannerConfigurer这个类注入到了IOC容器中。
在这里插入图片描述
可以看到,和之前@MapperScan对应上了,都是注册了MapperScannerConfigurer,也就是两种注解方式都是通过MapperScannerConfigurer扫描mapper注册的

下面我们仔细翻一下源码,看下MapperScannerConfigurer到底怎么处理@MapperScan和@Mapper
在这里插入图片描述
registerFilters方法指定了是走@Mapper注解扫描,还是@MapperScan包扫描

 public void registerFilters() {boolean acceptAllInterfaces = true;// 如果指定了扫描类型(@Mapper走这里)// annotationClass在前面的AutoConfiguredMapperScannerRegistrar#registerBeanDefinitions被注入// 就是这段builder.addPropertyValue("annotationClass", Mapper.class);if (this.annotationClass != null) {addIncludeFilter(new AnnotationTypeFilter(this.annotationClass));acceptAllInterfaces = false;}......// 如果没指定扫描类型,则扫描全部(@MapperScan走这里)if (acceptAllInterfaces) {addIncludeFilter((metadataReader, metadataReaderFactory) -> true);}// exclude package-info.javaaddExcludeFilter((metadataReader, metadataReaderFactory) -> {String className = metadataReader.getClassMetadata().getClassName();return className.endsWith("package-info");});
}

三.@MapperScan和@Mapper的使用建议

mapper接口所在包比较集中式可以在启动类上加@MapperScan注解指定mapper接口所在的包路径。

如果mapper接口所在的包路径比较分散(多部门,多人开发),建议直接在接口上加@Mapper注解,去掉启动类上的@MapperScan包扫描

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...