解决Spring使用@MapperScan问题

作者:「已注销」 时间:2021-11-01 23:55:13 

问题场景

今天小编在MyBatis 整合Spring 的时候,使用到了@MapperScan,在启动期出现了一个错误:

Invalid default: public abstract java.lang.Class org.mybatis.spring.annotation.MapperScan.factoryBean()

对于这个错误,小编也是倍感无奈,怎么会出现这个错误呢,看一下我的依赖有没有错误:


   compile(project(":spring-context"))
//    compile(project(":spring-instrument"))
   // https://mvnrepository.com/artifact/cglib/cglib
   compile group: 'cglib', name: 'cglib', version: '2.2.2'
   // https://mvnrepository.com/artifact/mysql/mysql-connector-java
   compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.21'
   // https://mvnrepository.com/artifact/org.mybatis/mybatis
   compile group: 'org.mybatis', name: 'mybatis', version: '3.5.2'
   // https://mvnrepository.com/artifact/org.mybatis/mybatis-spring
   compile group: 'org.mybatis', name: 'mybatis-spring', version: '2.0.2'

完全没得毛病呀, * ,究竟是哪里出现了问题呢,小编这时将SpringFramework 源码从github 上clone 下来了,导入idea 开始寻找问题所在。。。

问题根源

经过不懈的努力,小编终于找到了问题根源,在AnnotationsScanner 类中的这个方法:


static Annotation[] getDeclaredAnnotations(AnnotatedElement source, boolean defensive) {
 boolean cached = false;
 Annotation[] annotations = declaredAnnotationCache.get(source);
 if (annotations != null) {
  cached = true;
 }
 else {
  // 使用@MapperScan 的时候会报错,引入spring-jdbc 即可
  // 具体原因暂时还不清楚
  // Invalid default: public abstract java.lang.Class org.mybatis.spring.annotation.MapperScan.factoryBean()
  annotations = source.getDeclaredAnnotations();
  if (annotations.length != 0) {
   boolean allIgnored = true;
   for (int i = 0; i < annotations.length; i++) {
    Annotation annotation = annotations[i];
    if (isIgnorable(annotation.annotationType()) ||
      !AttributeMethods.forAnnotationType(annotation.annotationType()).isValid(annotation)) {
     annotations[i] = null;
    }
    else {
     allIgnored = false;
    }
   }
   annotations = (allIgnored ? NO_ANNOTATIONS : annotations);
   if (source instanceof Class || source instanceof Member) {
    declaredAnnotationCache.put(source, annotations);
    cached = true;
   }
  }
 }
 if (!defensive || annotations.length == 0 || !cached) {
  return annotations;
 }
 return annotations.clone();
}

AnnotatedElement 对于这个类,小编也是不太清楚,这时也倍感无奈,这个方法主要做的事情就是将Appconfig 配置类中的注解扫描下来,那会不会是注解的问题呢,在@MapperScan 注解的注释中发现小编的代码与MyBatis-Spring 开发团队提供的实例代码一致,这就让人想不明白了:


* <pre class="code">
* &#064;Configuration
* &#064;MapperScan("org.mybatis.spring.sample.mapper")
* public class AppConfig {
*
*   &#064;Bean
*   public DataSource dataSource() {
*     return new EmbeddedDatabaseBuilder().addScript("schema.sql").build();
*   }
*
*   &#064;Bean
*   public DataSourceTransactionManager transactionManager() {
*     return new DataSourceTransactionManager(dataSource());
*   }
*
*   &#064;Bean
*   public SqlSessionFactory sqlSessionFactory() throws Exception {
*     SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
*     sessionFactory.setDataSource(dataSource());
*     return sessionFactory.getObject();
*   }
* }
* </pre>

问题追溯

我这个时候被起疯了都,从GitHub 上由把mybatis-spring 的源码clone 了下来,导入idea,首先看一下mybatis-spring 的依赖:


<dependencies>
   <!-- Compile dependencies -->
   <dependency>
     <groupId>org.mybatis</groupId>
     <artifactId>mybatis</artifactId>
     <version>${mybatis.version}</version>
     <scope>provided</scope>
   </dependency>
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-context</artifactId>
     <version>${spring.version}</version>
     <scope>provided</scope>
   </dependency>
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-jdbc</artifactId>
     <version>${spring.version}</version>
     <scope>provided</scope>
   </dependency>
   <dependency>
     <groupId>org.springframework.batch</groupId>
     <artifactId>spring-batch-infrastructure</artifactId>
     <version>${spring-batch.version}</version>
     <scope>provided</scope>
   </dependency>

从依赖中看到了什么,tmd,<scope>provided</scope>,这个怎么讲,太无语了,其中它引入了spring-jdbc 的依赖。想象一下,@MapperScan 注解中是不是也使用到了spring-jdbc 的类,然后在使用@MapperScan 的时候没有加入spring-jdbc 的依赖,导致注解在扫描期间的错误,没毛病解释的通,找一下@MapperScan 中是否使用到了spring-jdbc 的依赖。

问题解决

果不其然,下面用一张图来看吧。

解决Spring使用@MapperScan问题

所以呢,在项目中加入spring-jdbc 完美解决。

SpringBoot  @MapperScan的注意事项

错误代码如下:

[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error invoking SqlProvider method (tk.mybatis.mapper.provider.base.BaseSelectProvider.dynamicSQL). Cause: java.lang.InstantiationException: tk.mybatis.mapper.provider.base.BaseSelectProvider] with root cause

检查@MapperScan导入的包是否为


import tk.mybatis.spring.annotation.MapperScan;

切记不要导成


import org.mybatis.spring.annotation.MapperScan

来源:https://blog.csdn.net/zhagnchong480/article/details/111562366

标签:Spring,@MapperScan
0
投稿

猜你喜欢

  • SpringBoot整合canal实现数据同步的示例代码

    2022-05-07 19:51:24
  • mybatis的插件机制示例详解

    2023-02-24 23:46:17
  • springboot ErrorPageFilter的实际应用详解

    2023-11-24 01:02:59
  • Spring Cloud Gateway不同频率限流的解决方案(每分钟,每小时,每天)

    2023-01-05 13:49:34
  • Spring整合MyBatis图示过程解析

    2023-11-13 11:45:09
  • 详谈Java中的Object、T(泛型)、?区别

    2022-06-11 21:13:11
  • java中SynchronizedList和Vector的区别详解

    2023-08-23 10:13:12
  • Java命令设计模式优雅解耦命令和执行提高代码可维护性

    2023-11-23 06:25:46
  • 教你使用java实现去除各种空格

    2022-09-21 21:27:07
  • 使用springboot跳转到指定页面和(重定向,请求转发的实例)

    2021-10-21 11:09:24
  • 利用Spring boot如何创建简单的web交互应用

    2023-07-15 12:47:00
  • Java遍历json字符串取值的实例

    2023-09-02 17:03:17
  • 基于Java文件输入输出流实现文件上传下载功能

    2023-08-10 11:50:32
  • 基于Transactional事务的使用以及注意说明

    2022-02-24 12:23:08
  • Spring @ComponentScan注解扫描组件原理

    2021-09-21 09:10:02
  • SpringBoot如何进行对象复制的实践

    2023-11-23 03:40:19
  • springboot日期转换器实现实例解析

    2023-01-31 13:16:45
  • Java的Swing编程中使用SwingWorker线程模式及顶层容器

    2021-09-09 08:45:06
  • Java可变个数形参的方法实例代码

    2023-01-15 18:35:56
  • Java事件机制要素及实例详解

    2022-11-27 07:10:53
  • asp之家 软件编程 m.aspxhome.com