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

目录
  • @MapperScan包扫描的坑
  • 手写一个@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<BeanScan> beanScanClass;
    /**
     *Class这个参数是使用@MapperScan这个类的class对象
    */
    public ArrayList<Class>  scan(Class aClass) throws ClassNotFoundException {

        //创建一个ArrayList存放生成的接口的class对象
        ArrayList<Class> 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接口,系统会自动的去扫描;

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

(0)

相关推荐

  • @MapperScan扫描包里混有@Service等问题如何解决

    目录 @MapperScan扫描包混有@Service 问题描述 解决办法一 解决办法二 解决办法三 解决办法四 解决办法五 @MapperScan包扫描的坑 在使用通用mapper执行查询时 找了半天才发现是包的问题 @MapperScan扫描包混有@Service 问题描述 @MapperScan注解配置的一般是dao或者mapper的扫描包,一般用于数据库操作,里面类的一般都是接口,如果在dao层有其他接口,比如说@Service等就会报错 解决办法一 把service包移走,方法可行 解

  • @MapperScan和@ComponentScan一块使用导致冲突的解决

    目录 @MapperScan和@ComponentScan一块使用冲突 解决方案 方案一 方案二 项目中@MapperScan和@Mapper共存之坑XxxMapper that could not be found. 尝试解决 @MapperScan和@ComponentScan一块使用冲突 项目集成了knief4j 报错: NoSuchBeanDefinitionException: No qualifying bean of type 'springfox.documentation.sc

  • mybatis注解之@Mapper和@MapperScan的使用

    目录 mybatis注解之@Mapper和@MapperScan 方式一:使用@Mapper注解 方式二:使用@MapperScan注解 @MapperScan和@Mapper区别及理解 作用 扫描一个包 扫描多个包 mybatis注解之@Mapper和@MapperScan 在使用Mybatis持久层框架来操作数据库时,我们可以使用@Mapper注解和@MapperScan注解来将Mapper接口类交给Sprinig进行管理. 方式一:使用@Mapper注解 优点:粒度更细 缺点:直接在Map

  • 基于@MapperScan和@ComponentScan的使用区别

    目录 @MapperScan和@ComponentScan区别 @MapperScan和@ComponentScan使用 原因 解决办法 课外拓展 @MapperScan和@ComponentScan区别 今天在撸SpringBoot的时候,突然对注解产生了混淆,@MapperScan和@ComponentScan都是扫描包,二者之间有什么区别呢? 首先,@ComponentScan是组件扫描注解,用来扫描@Controller @Service @Repository这类,主要就是定义扫描的路

  • @MapperScan注解与@Mapper注解的使用

    目录 @MapperScan注解与@Mapper注解使用 MapperScan注解和@Mapper的区别 @MapperScan注解与@Mapper注解使用 @Mapper一般对应一个接口,相当于一个mapper.xml文件,它的作用就是将接口生成一个动态代理类. 当我们写的mapper接口比较多的时候,我们没必须花太多时间一个一个的写,这样写太麻烦了,我们可以使用@ManpperScan注解,指明要扫描的包,它可以扫描所有的mapper文件. 它是如何做到的,我们可以查看里面的源码,主要起作用

  • Mybatis如何使用@Mapper和@MapperScan注解实现映射关系

    目录 使用@Mapper和@MapperScan注解实现映射关系 Mybatis-@MapperScan和mybatis:scan分析 <mybatis:scan> MapperScan 使用@Mapper和@MapperScan注解实现映射关系 MyBatis与Spring整合后需要实现实体和数据表的映射关系. 实现实体和数据表的映射关系可以在Mapper类上添加@Mapper注解,如下代码: /** * 用户信息Mapper动态代理接口 * @author pan_junbiao **/

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

    目录 @MapperScan包扫描的坑 手写一个@MapperScan扫描器 @MapperScan 自己手写该注解的思路 @MapperScan包扫描的坑 在使用通用mapper执行查询时,由于不太注意顺手就导了spring的包: import org.mybatis.spring.annotation.MapperScan; 结果就异常: tk.mybatis.mapper.provider.base.BaseSelectProvider:xxxx 找了半天才发现是包的问题,应该导mybat

  • 关于SpingMVC的<context:component-scan>包扫描踩坑记录

    目录 <context:component-scan>包扫描的坑 改动前 改动后 <context:component-scan>的使用说明 <context:annotation-config/>提供了两个子标签 <context:component-scan>包扫描的坑 公司项目配置的Spring项目的包扫描有点问题,出现了一个被Spring容器管理的Bean被创建了2次的现象.在此记录下解决的过程,方便后续查阅. 改动前 容器启动监听器中会扫描全部包,

  • springboot多模块包扫描问题的解决方法

    问题描述: springboot建立多个模块,当一个模块需要使用另一个模块的服务时,需要注入另一个模块的组件,如下面图中例子: memberservice模块中的MemberServiceApiImpl类需要注入common模块中的RedisService组件,该怎么注入呢? 解决: 在memberservice模块的启动类上加上RedisService类所在包的全路径的组件扫描,就像这样: 注意启动类上方的注解@ComponentScan(basePackages={"com.whu.comm

  • SpringBoot整合Mybatis无法扫描xml文件的解决

    网上说是使用idea在SpringBoot整合Mybatis时候会扫描不到xml文件 1.将xml文件放在resources下 2.在application.properties中配置xml文件的扫面 补充知识:Springboot整合mybatis /*.xml路径URl does not exist问题 解决一: 在配置文件下 扫描不到 xml文件: 原来的文件: <bean id="sqlSessionFactory" class="org.mybatis.spr

  • springboot 没法扫描到repository的解决

    sprint boot2.0启动的时候报错! A component required a bean of type 'XXX' that could not be found. 就是没有扫描到我的repository包里的代码 我先用@ComponentScan注解加上类所在的包名,没有报错,可以正常启动 但是坑爹的是@RestController注解下的Controller层的代码没有扫描到 就是说http://127.0.0.1:8080可以正常访问,但是Controller层配置的@Re

  • springBoot mybatis 包扫描实例

    springBoot mybatis 包扫描 @MapperScan(basePackages = {"com.zscat.*.dao","com.zscat.*.*.dao"}) @EnableTransactionManagement(proxyTargetClass = true) @SpringBootApplication @MapperScan(basePackages = {"com.zscat.*.dao","com.z

  • Android Studio工程导入及坑的解决

    目录 Androdi Studio 导入工程步骤 本地工程导入 远端库导入 检查点&修改方案 local.properties Gradle版本 Android版本 由于工作原因,需要将工程传递给一些新人小朋友,交互过程中,发现有几个典型的问题值得记录分享一下,以资来者. Androdi Studio 导入工程步骤 AS导入工程常用的有两种途径一种是通过本地工程导入,还有一种是从远端的版本管理仓拉取工程. 本地工程导入 本地工程导入比较简单,点击菜单File,然后找到Open...点击,便可以得

  • Golang时间处理中容易踩的坑分析解决

    目录 简介 类型 时区 小心有坑 时间解析的使用场景 时间操作 获取当前时间 时区设置 时间格式化(时间类型转字符串) 时间类型转时间戳 时间戳转时间类型 时间字符串转时间类型 时间计算 获取时间类型具体内容 时间加减 时间间隔(耗时) 时间取整(向上取整向下取整) 拓展 json时间转换 简介 在各个语言之中都有时间类型的处理,因为这个地球是圆的(我仿佛在讲废话),有多个时区,每个时区的时间不一样,在程序中有必要存在一种方式,或者说一种类型存储时间,还可以通过一系列的方法转换成不同国家的时间.

  • Android 弹出软键盘所遇到的坑及解决方法

    demo下载 重要代码: //1.此layout作为最外层的layout: //2.设置需要调整的view: setAdjustView(View view); //3.如果需要控制输入框的显示与隐藏,可以实现OnInputViewVisibleListener接口: public class SoftInputAdjustLayout extends RelativeLayout { private static final String TAG = SoftInputAdjustLayout

  • MySQL5.7中的sql_mode默认值带来的坑及解决方法

    在正常项目开发过程中,如果MySQL版本从5.6升级到5.7版本.作为DBA在考虑数据库版本升级带来的影响时,一般会有几个注意点: sql_mode optimizer_switch 本文主要内容是MySQL升级到5.7版本之后,由于默认的 sql_mode 值带来的坑以及对应的解决方案. 案例一:ONLY_FULL_GROUP_BY 问题描述 MySQL版本从5.6升级至5.7之后,部分SQL执行报错,报错信息如下: ERROR 1055 (42000): Expression #3 of X

随机推荐