天天看点

Spring使用@MapperScan 问题

问题场景

今天小编在

MyBatis

整合

Spring

的时候,使用到了

@MapperScan

,在启动期出现了一个错误:

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

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>

           

从依赖中看到了什么,他妈的,

<scope>provided</scope>

,这个怎么讲,太狗逼了,其中它引入了

spring-jdbc

的依赖。想象一下,

@MapperScan

注解中是不是也使用到了

spring-jdbc

的类,然后在使用

@MapperScan

的时候没有加入

spring-jdbc

的依赖,导致注解在扫描期间的错误,没毛病解释的通,找一下

@MapperScan

中是否使用到了

spring-jdbc

的依赖。

问题解决

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

Spring使用@MapperScan 问题

所以呢,在项目中加入

spring-jdbc

完美解决。

笔者留言

对于问题的解决方案还是是挺多的,送大家一句话 别向这个世界认输 因为你还有个牛逼的梦想。

Spring使用@MapperScan 问题