mybatis自动扫描mapper的工作原理
2015-07-21 12:35
357 查看
在mybatis中,我们可以在配置文件中使用自动扫描,也就是在mappers中使用package,但是mybatis的扫描原理是什么呢?
首先在mybatis中读取配置文件中的mappers元素,在这个元素中分成两类处理:mapper和package,mapper不在我们的讨论之内,我们只是研究package,这个标签就是自动扫描的配置.
下面是处理package的代码
跟踪源码,进入真正扫描将包中的内容是在如下代码
下面是我在跟踪源码时mapperSet的内容[class com.min.mapper.ItemsMapperTest, interface com.min.mapper.UserMapper, class com.min.mapper.OrderMapperTest$2, class com.min.mapper.UserMapperTest, class com.min.mapper.OrderMapperTest$1, interface com.min.mapper.ItemsMapper, interface
com.min.mapper.OrderMapper, class com.min.mapper.OrderMapperTest]
从中可以看出,这个是先将包中所有的类文件都加载了,在addMapper方法中进行了筛选,代码如下
如果你使用mapper已经配置了这个类的代理对象,如果这个类还在扫描包中,这时会报 Type interface com.min.mapper.UserMapper is already known to the MapperRegistry.l类型已经注册了,
如果当前类没有注册,那么mybatis会先扫描当前包中的类文件,在扫描包中的xml文件,具体代码可以跟踪org.apache.ibatis.binding.MapperRegistry类中的public <T> void addMapper(Class<T> type) 方法.
最后总结一下:
mybatis通过解析全局配置文件,解析到mappers时,在读取其中的所有元素,其中package为自动扫描的包.mybatis会将包中所有的类加载,循环判断其中的接口,并为其生成代理,
首先在mybatis中读取配置文件中的mappers元素,在这个元素中分成两类处理:mapper和package,mapper不在我们的讨论之内,我们只是研究package,这个标签就是自动扫描的配置.
下面是处理package的代码
String mapperPackage = child.getStringAttribute("name"); configuration.addMappers(mapperPackage);
跟踪源码,进入真正扫描将包中的内容是在如下代码
<pre name="code" class="java"> public void addMappers(String packageName, Class<?> superType) { ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<Class<?>>(); resolverUtil.find(new ResolverUtil.IsA(superType), packageName); Set<Class<? extends Class<?>>> mapperSet = resolverUtil.getClasses(); for (Class<?> mapperClass : mapperSet) { addMapper(mapperClass); } }}
下面是我在跟踪源码时mapperSet的内容[class com.min.mapper.ItemsMapperTest, interface com.min.mapper.UserMapper, class com.min.mapper.OrderMapperTest$2, class com.min.mapper.UserMapperTest, class com.min.mapper.OrderMapperTest$1, interface com.min.mapper.ItemsMapper, interface
com.min.mapper.OrderMapper, class com.min.mapper.OrderMapperTest]
从中可以看出,这个是先将包中所有的类文件都加载了,在addMapper方法中进行了筛选,代码如下
if (type.isInterface()) { if (hasMapper(type)) { throw new BindingException("Type " + type + " is already known to the MapperRegistry."); } boolean loadCompleted = false; try { knownMappers.put(type, new MapperProxyFactory<T>(type)); // It's important that the type is added before the parser is run // otherwise the binding may automatically be attempted by the // mapper parser. If the type is already known, it won't try. MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type); parser.parse(); loadCompleted = true; } finally { if (!loadCompleted) { knownMappers.remove(type); } } }在addMapper方法中,会对所有的接口生成代理,也就是如果你的不需要生成代理的接口如果放在自动扫描的包中,如果你没有配置相应的xml文件,将会报错,如果你配置了相应的文件,这时将会生成代理对象.
如果你使用mapper已经配置了这个类的代理对象,如果这个类还在扫描包中,这时会报 Type interface com.min.mapper.UserMapper is already known to the MapperRegistry.l类型已经注册了,
如果当前类没有注册,那么mybatis会先扫描当前包中的类文件,在扫描包中的xml文件,具体代码可以跟踪org.apache.ibatis.binding.MapperRegistry类中的public <T> void addMapper(Class<T> type) 方法.
最后总结一下:
mybatis通过解析全局配置文件,解析到mappers时,在读取其中的所有元素,其中package为自动扫描的包.mybatis会将包中所有的类加载,循环判断其中的接口,并为其生成代理,
相关文章推荐
- Android--小米奇葩bug
- objective-C面向对象理解(上)
- 【独立开发者er Cocos2d-x实战 011】Cocos2dx 3.x命令行生成APK详解
- Android代码混淆
- android Nine-Patch的使用(制作聊天界面必学)
- listview的简单使用(Baseadapter)
- 《Swift程序设计语言》中国翻译和学习笔记page23
- Android屏蔽返回键
- Android 基于Proxy/Delegate 实现bug热修复
- android获取string.xml的值
- android 通过UncaughtExceptionHandler 捕获RuntimeException,并将捕获到的信息上传到友盟
- Android 4.4 外置卡
- 移动端滑动方向判断
- Android 项目框架
- Apk签名
- app发布证书、真机调试证书、测试证书、推送证书详细过程
- Android Studio NDK编译Error
- unity3d 血液
- ios设备抓包方法
- android应用移动到SD卡_如何允许移动?_android:installLocation属性使用