关于@MapperScan包扫描的坑及解决

这篇文章主要介绍了关于@MapperScan包扫描的坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

@MapperScan包扫描的坑

在使用通用mapper执行查询时,由于不太注意顺手就导了spring的包:

import org.mybatis.spring.annotation.MapperScan;

结果就异常:

tk.mybatis.mapper.provider.base.BaseSelectProvider:xxxx

找了半天才发现是包的问题,应该导mybatis的MapperScan而不是spring中的包,正确的包名:

import tk.mybatis.spring.annotation.MapperScan;

手写一个@MapperScan扫描器

@MapperScan

1.@MapperScan这个注解是由MyBatis提供的;

2.只能使用在类上;

3.主要功能是扫描到指定包下接口的生成Class对象

注解使用在类上,指定value的值可以指定扫描的包,把扫描到的包中的接口,生成动态代理注入到Spring的ioc容器中;

自己手写该注解的思路

1.需要使用一个类,把使用这个注解的类加载加载(把Class对象注册进来);

2.解析这个类上是否有@MapperScan注解;

3.然后解析@MapperScan注解上的value值得到接口的路径;

4.根据路径扫描有哪些接口;

5.根据接口名和classpath路径,把接口加载进来;

6.把接口的class对象保存在List中;

#7.接下来就是Mybatis框架生成动态代理;

注解:

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface BeanScan {     String value(); }
//生成MapperScan这个类的处理逻辑 public class MapperScan { //通过解析BeanScan来得到文件目录 Class beanScanClass; /** *Class这个参数是使用@MapperScan这个类的class对象 */ public ArrayList  scan(Class aClass) throws ClassNotFoundException { //创建一个ArrayList存放生成的接口的class对象 ArrayList mapperName = new ArrayList<>(); //解析传入的aclass对象得到@MapperSCan这个注解 //BeanScan这个我们定义的@mapperScan注解 BeanScan BeanScan = (com.scan.BeanScan) aClass.getDeclaredAnnotation(BeanScan.class); //通过BeanScan对象的到接口的路径 String path = BeanScan.value(); //获得当前的类加载器(可以用类加载器得到classpath,然后使用File对象操作文件) ClassLoader classLoader = aClass.getClassLoader(); //接口的路径是"."转换成"\" String replacePath = path.replace(".", "\\"); //通过类加载器获取当前文件的绝对路径 URL resource = classLoader.getResource(replacePath); //通过文件的绝对路径把文件编程File对象 String file = resource.getFile(); File file1 = new File(file); //判断File对象是否是目录 if(file1.isDirectory()){ //把File对象下的文件名称取出来 File[] files = file1.listFiles(); for (File f :files) { //字符串拼接操作(把字符串拼接成系统类加载器可以加载的格式) String name1 = file1.getName(); String name = f.getName(); String pathName = name1+"."+name; String substring = pathName.substring(0, pathName.indexOf(".class")); //把接口的全限定名称传入生成class对象,放入到list集合中 Class aClass1 = ClassLoader.loadClass(substring); mapperName.add(aClass1); System.out.println(aClass1); } } return mapperName; } }

#有了这个注解后,我们就不用手动去传入接口的class对象来生成动态代理

只需要在指定的文件下在创建Mapper接口,系统会自动的去扫描; 

以上为个人经验,希望能给大家一个参考,也希望大家多多支持0133技术站。 

以上就是关于@MapperScan包扫描的坑及解决的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » Java