经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring Boot » 查看文章
关于@MapperScan包扫描的坑及解决
来源:jb51  时间:2022/8/16 13:27:03  对本文有异议

@MapperScan包扫描的坑

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

  1. import org.mybatis.spring.annotation.MapperScan;

结果就异常:

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

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

  1. 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框架生成动态代理;

注解:

  1. @Retention(RetentionPolicy.RUNTIME)
  2. @Target(ElementType.TYPE)
  3. public @interface BeanScan {
  4. ? ? String value();
  5. }
  1. //生成MapperScan这个类的处理逻辑
  2. public class MapperScan {
  3. //通过解析BeanScan来得到文件目录
  4. Class<BeanScan> beanScanClass;
  5. /**
  6. *Class这个参数是使用@MapperScan这个类的class对象
  7. */
  8. public ArrayList<Class> scan(Class aClass) throws ClassNotFoundException {
  9. //创建一个ArrayList存放生成的接口的class对象
  10. ArrayList<Class> mapperName = new ArrayList<>();
  11. //解析传入的aclass对象得到@MapperSCan这个注解
  12. //BeanScan这个我们定义的@mapperScan注解
  13. BeanScan BeanScan = (com.scan.BeanScan) aClass.getDeclaredAnnotation(BeanScan.class);
  14. //通过BeanScan对象的到接口的路径
  15. String path = BeanScan.value();
  16. //获得当前的类加载器(可以用类加载器得到classpath,然后使用File对象操作文件)
  17. ClassLoader classLoader = aClass.getClassLoader();
  18. //接口的路径是"."转换成"\"
  19. String replacePath = path.replace(".", "\\");
  20. //通过类加载器获取当前文件的绝对路径
  21. URL resource = classLoader.getResource(replacePath);
  22. //通过文件的绝对路径把文件编程File对象
  23. String file = resource.getFile();
  24. File file1 = new File(file);
  25. //判断File对象是否是目录
  26. if(file1.isDirectory()){
  27. //把File对象下的文件名称取出来
  28. File[] files = file1.listFiles();
  29. for (File f :files) {
  30. //字符串拼接操作(把字符串拼接成系统类加载器可以加载的格式)
  31. String name1 = file1.getName();
  32. String name = f.getName();
  33. String pathName = name1+"."+name;
  34. String substring = pathName.substring(0, pathName.indexOf(".class"));
  35. //把接口的全限定名称传入生成class对象,放入到list集合中
  36. Class<?> aClass1 = ClassLoader.loadClass(substring);
  37. mapperName.add(aClass1);
  38. System.out.println(aClass1);
  39. }
  40. }
  41. return mapperName;
  42. }
  43. }

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

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

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号