Mybatis下面的MapperScannerConfigurer 扫描器
Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring
Mybatis在与Spring集成的时候可以配置 MapperFactoryBean来生成Mapper接口的代理. 例如
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"><property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" /><property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean>
MapperFactoryBean 创建的代理类实现了 UserMapper 接口,并且注入到应用程序中。 因为代理创建在运行时环境中(Runtime,译者注) ,那么指定的映射器必须是一个接口,而 不是一个具体的实现类。
上面的配置有一个很大的缺点,就是系统有很多的配置文件时 全部需要手动编写,所以上述的方式已经很用了。
没有必要在 Spring 的 XML 配置文件中注册所有的映射器。相反,你可以使用一个 MapperScannerConfigurer , 它 将 会 查 找 类 路 径 下 的 映 射 器 并 自 动 将 它 们 创 建 成 MapperFactoryBean。
要创建 MapperScannerConfigurer,可以在 Spring 的配置中添加如下代码:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="org.mybatis.spring.sample.mapper" /> </bean>
basePackage 属性是让你为映射器接口文件设置基本的包路径。 你可以使用分号或逗号 作为分隔符设置多于一个的包路径。每个映射器将会在指定的包路径中递归地被搜索到。
注 意 , 没 有 必 要 去 指 定 SqlSessionFactory 或 SqlSessionTemplate , 因 为 MapperScannerConfigurer 将会创建 MapperFactoryBean,之后自动装配。但是,如果你使 用了一个 以上的 DataSource ,那 么自动 装配可 能会失效 。这种 情况下 ,你可 以使用 sqlSessionFactoryBeanName 或 sqlSessionTemplateBeanName 属性来设置正确的 bean 名 称来使用。这就是它如何来配置的,注意 bean 的名称是必须的,而不是 bean 的引用,因 此,value 属性在这里替代通常的 ref:
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
MapperScannerConfigurer 支 持 过 滤 由 指 定 的 创 建 接 口 或 注 解 创 建 映 射 器 。 annotationClass 属性指定了要寻找的注解名称。 markerInterface 属性指定了要寻找的父 接口。如果两者都被指定了,加入到接口中的映射器会匹配两种标准。默认情况下,这两个 属性都是 null,所以在基包中给定的所有接口可以作为映射器加载。
被发现的映射器将会使用 Spring 对自动侦测组件(参考 Spring 手册的 3.14.4)默认的命 名策略来命名。也就是说,如果没有发现注解,它就会使用映射器的非大写的非完全限定类 名。但是如果发现了@Component 或 JSR-330 的@Named 注解,它会获取名称。注意你可以 配 置 到 org.springframework.stereotype.Component , javax.inject.Named(如果你使用 JSE 6 的话)或你自己的注解(肯定是自我注解)中,这 样注解将会用作生成器和名称提供器。
接下来让我们看一下MapperScannerConfigurer类的源码 看看是如何自动扫描的。
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {2 if (this.processPropertyPlaceHolders) {3 processPropertyPlaceHolders();4 }5 6 ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);7 scanner.setAddToConfig(this.addToConfig);8 scanner.setAnnotationClass(this.annotationClass);9 scanner.setMarkerInterface(this.markerInterface);
10 scanner.setSqlSessionFactory(this.sqlSessionFactory);
11 scanner.setSqlSessionTemplate(this.sqlSessionTemplate);
12 scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);
13 scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);
14 scanner.setResourceLoader(this.applicationContext);
15 scanner.setBeanNameGenerator(this.nameGenerator);
16 scanner.registerFilters();
17 scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
18 }把Mapper接口转换成MapperFactoryBean的代码在地17行这个方法里,让我们跟踪进去看一下。 1 @Override2 public Set<BeanDefinitionHolder> doScan(String... basePackages) {3 Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);4 5 if (beanDefinitions.isEmpty()) {6 logger.warn("No MyBatis mapper was found in '" + Arrays.toString(basePackages) + "' package. Please check your configuration.");7 } else {8 for (BeanDefinitionHolder holder : beanDefinitions) {9 GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();
10
11 if (logger.isDebugEnabled()) {
12 logger.debug("Creating MapperFactoryBean with name '" + holder.getBeanName()
13 + "' and '" + definition.getBeanClassName() + "' mapperInterface");
14 }
15
16 // the mapper interface is the original class of the bean
17 // but, the actual class of the bean is MapperFactoryBean
18 //把接口的类型设置进去
19 definition.getPropertyValues().add("mapperInterface", definition.getBeanClassName());
20 //设置Bean的真实类型MapperFactoryBean
21 definition.setBeanClass(MapperFactoryBean.class);
22 //是否把Mapper接口加入到Mybatis的Config当中去
23 definition.getPropertyValues().add("addToConfig", this.addToConfig);
24
25 boolean explicitFactoryUsed = false;
26 //如果sqlSessionFactoryBeanName的名字不为空 则在Spring容器中查询
27 //适合多数据源
28 if (StringUtils.hasText(this.sqlSessionFactoryBeanName)) {
29 definition.getPropertyValues().add("sqlSessionFactory", new RuntimeBeanReference(this.sqlSessionFactoryBeanName));
30 explicitFactoryUsed = true;
31 } else if (this.sqlSessionFactory != null) {
32 definition.getPropertyValues().add("sqlSessionFactory", this.sqlSessionFactory);
33 explicitFactoryUsed = true;
34 }
35
36 //如果sqlSessionTemplateBeanName的名字不为空 则在Spring容器中查询
37 //适合多数据源
38 if (StringUtils.ha
39 if (StringUtils.hasText(this.sqlSessionTemplateBeanName)) {
40 if (explicitFactoryUsed) {
41 logger.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.");
42 }
43 definition.getPropertyValues().add("sqlSessionTemplate", new RuntimeBeanReference(this.sqlSessionTemplateBeanName));
44 explicitFactoryUsed = true;
45 } else if (this.sqlSessionTemplate != null) {
46 if (explicitFactoryUsed) {
47 logger.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.");
48 }
49 definition.getPropertyValues().add("sqlSessionTemplate", this.sqlSessionTemplate);
50 explicitFactoryUsed = true;
51 }
52
53 if (!explicitFactoryUsed) {
54 if (logger.isDebugEnabled()) {
55 logger.debug("Enabling autowire by type for MapperFactoryBean with name '" + holder.getBeanName() + "'.");
56 }
57 definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
58 }
59 }
60 }
61 //这个集合返回以后 Spring容器会将里面的所有内容注册到容器中
62 return beanDefinitions;
63 }
转载于:https://www.cnblogs.com/xiohao/p/4701036.html
Mybatis下面的MapperScannerConfigurer 扫描器相关推荐
- 解决spring整合mybatis时错误 ‘org.mybatis.spring.mapper.MapperScannerConfigurer#0‘
警告:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.mybat ...
- sonarqube中,分析maven聚合工程时,不必分析parent工程,只需分析下面的module子工程即可
sonarqube中,分析maven聚合工程时,不必分析parent工程,只需分析下面的module子工程即可 cd ../../xxx-sms # mvn clean org.jacoco:jaco ...
- Java黑皮书课后题第8章:*8.30(代数:解答线性方程)编写一个方法,解答下面的2*2线性方程组系统
*8.30(代数:解答线性方程)编写一个方法,解答下面的2*2线性方程组系统 题目 题目描述 代码 题目 题目描述 8.30(代数:解答线性方程)编写一个方法,解答下面的22线性方程组系统: a00 ...
- Java黑皮书课后题第5章:**5.35(加法)编写程序,计算下面的和:1/(1+根2) + 1/(根2+根3) + 1/(根3+根4)+……1/(根624+根625)
@[TOC](5.35(加法)编写程序,计算下面的和:1/(1+根2) + 1/(根2+根3) + 1/(根3+根4)+--1/(根624+根625)) 题目 题目概述 5.35(加法)编写程序,计算 ...
- windows下面的txt在linux下面显示为乱码
windows下面的txt正确保存操作后, 传递到linux,发现是乱码. 解决方案: linux下面,整个txt文件拖入chrome浏览器,然后把浏览器里面的内容重新保存即可
- Ubuntu16.04下面的vs code出现Unable to activate CppCheck analyzer
Ubuntu16.04下面的vs code出现Unable to activate CppCheck analyzer 解决方案: synaptic管理器中安装cppcheck和cppcheck-gu ...
- Android之非root手机run-as命令获取debug版本apk里面的数据(shared_prefs文件,lib下面的so,数据库文件)
1 问题 非root手机想要获取debug版本的apk里面的数据(shared_prefs文件,lib下面的so,数据库文件) 2 直接用run-as命令 adb shellrun-as pack ...
- 根据div 标签 查看数组@class=modulwrap 下面的/table/tbody/tr/td
<div class="modulwrap"><div class="request_title"><span class=&qu ...
- java 下面的while语句退出时_java 下面的while语句退出时
java 下面的while语句退出时 [2021-02-02 07:01:21] 简介: php中while循环语句的使用方法是:while循环语句在指定条件为true时执行代码块.while循环语 ...
- linux下面的j2sdk的安装和配置过程
linux下面的j2sdk的安装和配置过程! 1.下载一个Linux Platform的JDK,建议下载RPM自解压格式的 (RPM in self-extracting file,j2sdk-1_4 ...
最新文章
- Windows 各种计时函数总结
- openresty开发系列24--openresty中lua的引入及使用
- sqlite 字符串 转 整型 cast 函数 (强制类型转换 )
- 软件工程综合实践专题——个人博客作业1
- 【nyoj-456】 邮票分你一半 (dp,0-1背包的中点问题)
- php多线程模拟请求,浅谈php使用curl模拟多线程发送请求
- 视频下载比想象中容易
- inno setup打包的安装包如何在卸载完程序后可以继续安装_这两个方法就够了!快速制作Python程序Windows安装包...
- PostgreSQL数据库远程连接功能的开启
- 自由在博客里插入广告,有钱你不赚吗???
- oracle掉电后ora 00600,ORA-00600: 内部错误代码, 参数: [kcratr1_lastbwr](转)
- PostgreSQL(1)数据库安装(win和linux)
- 【SEW-伺服电机-Profinet-io通讯控制——伺服配置】
- java 请求webservice_JAVA调用WebService实例
- 马哥linux多道处理程序,马哥linux课堂笔记
- 日系PC厂商为问题希捷硬盘提供固件更新
- 《一课经济学》六、政府价格管制
- C语言编程 5.7 从键盘中输入一个英文字母,如果它是大写则转化为小写。如果它是小写则转化为大写,并将其ASCll码显示到屏幕上。
- 运行maven打包的项目jar包
- ThinkPHP 5.0常用助手函数
热门文章
- SourceAnalysis/Binder源码分析.md
- WPF中实现图片文件转换成Visual对象,Viewport3D对象转换成图片
- 转载 网络上的8051 free IP core资源
- Yii 2.0 权威指南 (8) 配合数据库使用
- leetcode探索队列和栈(一)
- java图形化元件竖直排列_Java:图形化比较排序
- ubuntu 打开ssh登陆_Ubuntu开启SSH远程登录
- gpu opencl 向量加_【Embedding】GloVe:大规模语料中快速训练词向量
- ROS踩坑日记(2)----ERROR: cannot download default sources list from:
- linux用户一个用户只能一个用户组,为什么linux用户可以属于多个用户组,文件只能属于一个用户组?...