问题场景
今天小编在
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">
* @Configuration
* @MapperScan("org.mybatis.spring.sample.mapper")
* public class AppConfig {
*
* @Bean
* public DataSource dataSource() {
* return new EmbeddedDatabaseBuilder().addScript("schema.sql").build();
* }
*
* @Bean
* public DataSourceTransactionManager transactionManager() {
* return new DataSourceTransactionManager(dataSource());
* }
*
* @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
的依赖。
问题解决
果不其然,下面用一张图来看吧。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiIXZ05WZj91YpB3IwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSPBR0TwMWbiZHaykVdkdVWvB3MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL3cDN2MTNwgTMyIjMxAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
所以呢,在项目中加入
spring-jdbc
完美解决。
笔者留言
对于问题的解决方案还是是挺多的,送大家一句话 别向这个世界认输 因为你还有个牛逼的梦想。