您的位置:首页 > 移动开发

mybatis自动扫描mapper的工作原理

2015-07-21 12:35 357 查看
在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会将包中所有的类加载,循环判断其中的接口,并为其生成代理,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: