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

目录
  • @MapperScan扫描包混有@Service
    • 问题描述
    • 解决办法一
    • 解决办法二
    • 解决办法三
    • 解决办法四
    • 解决办法五
  • @MapperScan包扫描的坑
    • 在使用通用mapper执行查询时
    • 找了半天才发现是包的问题

@MapperScan扫描包混有@Service

问题描述

@MapperScan注解配置的一般是dao或者mapper的扫描包,一般用于数据库操作,里面类的一般都是接口,如果在dao层有其他接口,比如说@Service等就会报错

解决办法一

把service包移走,方法可行

解决办法二

不使用@MapperScan,在每个dao或者mapper里面加上注解@Mapper,方法可行

解决办法三

使用自定义注解,在mybatis的注解比较完善的情况下,就不用自己搞多少

创建注解@MyMapperScan

里面的属性全部抄袭@MapperScan

MapperScannerRegistrar换成自己的

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MyMapperScannerRegistrar.class)
@Repeatable(MapperScans.class)
public @interface MapperScan {
  String[] value() default {};
  String[] basePackages() default {};

  Class<?>[] basePackageClasses() default {};

  Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
  Class<? extends Annotation> annotationClass() default Annotation.class;
  Class<?> markerInterface() default Class.class;

  String sqlSessionTemplateRef() default "";
  String sqlSessionFactoryRef() default "";

  Class<? extends MapperFactoryBean> factoryBean() default MapperFactoryBean.class;
  String lazyInitialization() default "";
}

MyMapperScannerRegistrar扫描注册器

这个类和mybatis的一模一样,唯一的不同就是MyClassPathMapperScanner是自己的扫描

public class MyMapperScannerRegistrar extends MapperScannerRegistrar {
    private ResourceLoader resourceLoader;
    /**
     * {@inheritDoc}
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AnnotationAttributes annoAttrs = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));
        //这个是自己的
        ClassPathMapperScanner scanner = new MyClassPathMapperScanner(registry);
        // this check is needed in Spring 3.1
        if (resourceLoader != null) {
            scanner.setResourceLoader(resourceLoader);
        }
        Class<? extends Annotation> annotationClass = annoAttrs.getClass("annotationClass");
        if (!Annotation.class.equals(annotationClass)) {
            scanner.setAnnotationClass(annotationClass);
        }
        Class<?> markerInterface = annoAttrs.getClass("markerInterface");
        if (!Class.class.equals(markerInterface)) {
            scanner.setMarkerInterface(markerInterface);
        }
        Class<? extends BeanNameGenerator> generatorClass = annoAttrs.getClass("nameGenerator");
        if (!BeanNameGenerator.class.equals(generatorClass)) {
            scanner.setBeanNameGenerator(BeanUtils.instantiateClass(generatorClass));
        }
        Class<? extends MapperFactoryBean> mapperFactoryBeanClass = annoAttrs.getClass("factoryBean");
        if (!MapperFactoryBean.class.equals(mapperFactoryBeanClass)) {
            scanner.setMapperFactoryBean(BeanUtils.instantiateClass(mapperFactoryBeanClass));
        }
        scanner.setSqlSessionTemplateBeanName(annoAttrs.getString("sqlSessionTemplateRef"));
        scanner.setSqlSessionFactoryBeanName(annoAttrs.getString("sqlSessionFactoryRef"));
        List<String> basePackages = new ArrayList<String>();
        for (String pkg : annoAttrs.getStringArray("value")) {
            if (StringUtils.hasText(pkg)) {
                basePackages.add(pkg);
            }
        }
        for (String pkg : annoAttrs.getStringArray("basePackages")) {
            if (StringUtils.hasText(pkg)) {
                basePackages.add(pkg);
            }
        }
        for (Class<?> clazz : annoAttrs.getClassArray("basePackageClasses")) {
            basePackages.add(ClassUtils.getPackageName(clazz));
        }
        scanner.registerFilters();
        scanner.doScan(StringUtils.toStringArray(basePackages));
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }
}

MyClassPathMapperScanner

自己的扫描类基本也是mybatis的,就是在判断上面改动了一点点

public class MyClassPathMapperScanner extends ClassPathMapperScanner {
    public MyClassPathMapperScanner(BeanDefinitionRegistry registry) {
        super(registry);
    }
    @Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        boolean flag = super.isCandidateComponent(beanDefinition);
        //包名带有Mapper的才会被mybatis代理
        boolean mapper = beanDefinition.getBeanClassName().contains("Mapper");
        return flag && mapper;
    }
}

现在只需要用自己的扫描注解即可,用法和mybatis的一模一样

解决办法四

这个是针对第三点的,作者使用第三点的时候mybatis版本为3.4.6

mybatis-spring版本为1.3.2,spring版本为5.x

当mybatis版本为3.5.2的mybatis-spring版本为2.0.2的时候

MapperScannerRegistrar类扫描的方式发生了一点点变化,

还需要改写MapperScannerConfigurer类,其他的不变

完毕!

解决办法五

@MapperScan注解使用markerInterface或者annotationClass参数限制扫描的接口

@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;

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

(0)

相关推荐

  • 浅谈@mapper引入不到引入的是@MapperScan的问题

    两种防水都可以,但是使用方式不同. @mapper需要mybatis和mybatis-spring的版本足够的高才可以. 不然导入不到@mapper. 补充知识:关于MyBatis的@Mapper和@MapperScan注解的一点思考 最近有空回顾mybatis,想起@Mapper注解一直没弄明白是干嘛的,代码上的注释写的很简单(Marker interface for MyBatis mappers),开发过程中也没用到,但网上各种资料偶有出现他的身影.问了度娘,都没讲清楚,我决定自己思考下这

  • 解决Spring使用@MapperScan问题

    目录 问题场景 问题根源 问题追溯 问题解决 SpringBoot  @MapperScan的注意事项 问题场景 今天小编在MyBatis 整合Spring 的时候,使用到了@MapperScan,在启动期出现了一个错误: Invalid default: public abstract java.lang.Class org.mybatis.spring.annotation.MapperScan.factoryBean() 对于这个错误,小编也是倍感无奈,怎么会出现这个错误呢,看一下我的依赖

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

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

  • 基于MapperXML扫描的问题

    目录 MapperXML扫描的问题 1.如果将XML放在java目录下 2.如果放resources下,则在.properties下配置 说明 mybatis自动扫描XML文件填坑 MapperXML扫描的问题 1.如果将XML放在java目录下 则需要在pom包里配置路径.或者就扫描不到. 如下图所示: 2.如果放resources下,则在.properties下配置 如下图所示: 说明 mapper注解配置文件 @MapperScan 作用:将对应的mapper下面的mapper类自动添加@

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

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

  • 注入jar包里的对象,用@autowired的实例

    注入的jar包如果不能直接使用 @autowired 来使用,可以采用如下方法: @Configuration public class DemoConfiguration { @Bean public Demo demo() { return new Demo(); //该对象为Jar包对象 } } 补充知识:引入第三方包 @Autowired Spring注入失败解决方案 一.问题背景 开发工程中,我负责的微服务需要依赖中台服务层,在调用该服务的功能接口时,@Autowired 注入方式启动

  • java实现一个扫描包的工具类实例代码

    前言 在很多的实际场景中,我们需要得到某个包名下面所有的类,比如我们在使用SpringMVC的时候,知道SpringMVC可以扫描指定包下的所有类,在平时的开发中,我们也有这样的场景,所以今天写一个扫描包的工具类,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 代码如下: package com.gujin.utils; import java.io.File; import java.io.FileFilter; import java.io.IOException; imp

  • SpringMVC和Spring的配置文件扫描包详解

    在Spring整体框架的核心概念中,容器是核心思想,就是用来管理Bean的整个生命周期的,而在一个项目中,容器不一定只有一个,Spring中可以包括多个容器,而且容器有上下层关系,目前最常见的一种场景就是在一个项目中引入Spring和SpringMVC这两个框架,那么它其实就是两个容器,Spring是父容器,SpringMVC是其子容器,并且在Spring父容器中注册的Bean对于SpringMVC容器中是可见的,而在SpringMVC容器中注册的Bean对于Spring父容器中是不可见的,也就

  • springboot 无法扫描到父类模块中Bean的原因及解决

    目录 springboot 无法扫描到父类模块中Bean 现象: 如何解决 解决方案 spring boot 启动就自动关闭 之 找不到bean 解决方法: 原因: 以下收集别的解释: 所以有两种解决办法: springboot 无法扫描到父类模块中Bean 现象: 我定义了两个模块 A 和 B .B模块依赖A模块 A模块中我定义了一个@Component 却发现在B模块中我无法扫描到这个Bean导入注入失败 如何解决 查阅得知,在springboot中的bean扫描是扫描同级目录或者下级目录,

  • 外层竖向ScrollView,里层横向ScrollView滑动冲突的解决方法

    实例如下: public class CustomScrollView extends ScrollView { private GestureDetector mGestureDetector; View.OnTouchListener mGestureListener; @SuppressWarnings("deprecation") public CustomScrollView(Context context,AttributeSet attrs) { super(contex

  • pycharm中下载的包但是import还是无法使用/报红的解决方法

    目录 一.查看当前使用的虚拟环境是否是自己想要使用的解释器 二.在文件(file)-设置(settings)中查看项目解释器中是否有自己需要的包 三.pycham中显示有包,但是import导包还是报红 总结 查看自己的虚拟环境是否使用正确 一.查看当前使用的虚拟环境是否是自己想要使用的解释器 查看解释器所在目录是否为想要使用的虚拟环境所在目录 二.在文件(file)-设置(settings)中查看项目解释器中是否有自己需要的包 三.pycham中显示有包,但是import导包还是报红 报错原因

  • idea maven项目无法识别jar包里的class解决方案

    idea maven不识别jar包的class 我用new project from exit source ,项目依赖下载完成后install能成功,项目也能运行. 但是代码所有用到第三方库的地方都报错 无法识别jar里的class,如图所示: 解决办法 使用 import project . 导入项目的时候选择pom.xml文件,别选项目文件夹应该就不会出现这个问题了 idea maven打包失败,找不到引用的jar文件的类 在开发环境下Maven一切运行顺利,可是打包时就报错,说是找不到符

  • 安装MySQL在最后的start service停住了解决方法

    由于我的MySQL不知道什么原因突然打不开了并报了个10061的错,查了下原因说是因为数据库被连接发生冲突,麻烦死了于是重装,在最后一步的 start service 停了,安装失败,又重装了N次,还是失败.原因是已经装过MySQL的电脑上存在以注册项目,网上有很多说法,和方法,我试了一个成功了.基本步骤一下: 1.卸载MySQL应用程序,要把MySQL的服务业卸载掉,命令窗口使用: sc delete MySQL 2.清理注册表(找出来删掉) 复制代码 代码如下: HKEY_LOCAL_MAC

  • Ajax获取到数据放入echarts里不显示的原因分析及解决办法

    在做一个需要用到echarts地图的项目的时候,成功通过ajax获取到了后台提供的数据,并生成了想要的JSON串.但是,放到echarts option.series[0].data里,获取不到数据.在生成的地图上无法看到你从后台获取到的值.翻遍百度和必应,给出的答案五花八门,仍旧未解决问题,最后还是一个同事大牛给解决的,在此分享给大家.希望对大家有帮助,,,, 废话不多说,直接上码: $(function () { var data = []; function setOption(data)

随机推荐