解決Spring使用@MapperScan問題
問題場景
今天小編在MyBatis 整合Spring 的時候,使用到了@MapperScan,在啟動期出現(xiàn)了一個錯誤:
Invalid default: public abstract java.lang.Class org.mybatis.spring.annotation.MapperScan.factoryBean()
對于這個錯誤,小編也是倍感無奈,怎么會出現(xiàn)這個錯誤呢,看一下我的依賴有沒有錯誤:
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'
完全沒得毛病呀,他媽的,究竟是哪里出現(xiàn)了問題呢,小編這時將SpringFramework 源碼從github 上clone 下來了,導(dǎo)入idea 開始尋找問題所在。。。
問題根源
經(jīng)過不懈的努力,小編終于找到了問題根源,在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 注解的注釋中發(fā)現(xiàn)小編的代碼與MyBatis-Spring 開發(fā)團隊提供的實例代碼一致,這就讓人想不明白了:
* <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 了下來,導(dǎo)入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 的依賴,導(dǎo)致注解在掃描期間的錯誤,沒毛病解釋的通,找一下@MapperScan 中是否使用到了spring-jdbc 的依賴。
問題解決
果不其然,下面用一張圖來看吧。

所以呢,在項目中加入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導(dǎo)入的包是否為
import tk.mybatis.spring.annotation.MapperScan;
切記不要導(dǎo)成
import org.mybatis.spring.annotation.MapperScan
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
sonar-scanner連接sonarquebe7的sonar.java.binaries問題的解決方案
今天小編就為大家分享一篇關(guān)于sonar-scanner連接sonarquebe7的sonar.java.binaries問題的解決方案,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12
IntelliJ IDEA安裝目錄和設(shè)置目錄的說明(IntelliJ IDEA快速入門)
這篇文章主要介紹了IntelliJ IDEA安裝目錄和設(shè)置目錄的說明(IntelliJ IDEA快速入門),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04
Spring中@Repository注解的作用和用法以及和@Mapper的區(qū)別詳析
這篇文章主要給大家介紹了關(guān)于Spring中@Repository注解的作用和用法以及和@Mapper的區(qū)別的相關(guān)資料,注解的作用是標(biāo)識一個類為數(shù)據(jù)訪問對象,并由Spring框架進行實例化和管理,需要的朋友可以參考下2023-09-09
Spring中@Configuration注解和@Component注解的區(qū)別詳解
這篇文章主要介紹了Spring中@Configuration注解和@Component注解的區(qū)別詳解,@Configuration 和 @Component 到底有何區(qū)別呢?我先通過如下一個案例,在不分析源碼的情況下,小伙伴們先來直觀感受一下這兩個之間的區(qū)別,需要的朋友可以參考下2023-09-09
java 定時器Timer和TimerTask的使用詳解(執(zhí)行和暫停)
這篇文章主要介紹了java 定時器Timer和TimerTask的使用詳解(執(zhí)行和暫停),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-11-11
Spring Boot與Spring Security的跨域問題解決方案
跨域問題是指在Web開發(fā)中,瀏覽器出于安全考慮,限制了不同域名之間的資源訪問,本文重點給大家介紹Spring Boot與Spring Security的跨域問題解決方案,感興趣的朋友一起看看吧2023-09-09
在安卓系統(tǒng)中插入表情到光標(biāo)位置的代碼詳解
這篇文章主要介紹了在安卓系統(tǒng)中插入表情到光標(biāo)位置的代碼詳解,利用Java代碼在EditText控件中實現(xiàn),需要的朋友可以參考下2015-07-07

