在使用 Spring Boot 構建多模塊項目,集成 MyBatis-Plus 時,很多開發者會遇到類似如下啟動報錯:
Error creating bean with name 'mapperScannerConfigurer' ...
Caused by: java.lang.IllegalArgumentException: Property 'basePackage' is required
即使在啟動類上正確添加了 @MapperScan("com.xxx.mapper")
,項目依然報錯無法啟動。這到底是怎么回事?我們該如何優雅地配置 Mapper
掃描?本文將逐步分析問題成因,最后給出推薦方案。
一、問題背景
項目結構如下(典型的多模塊結構):
parent
├── common # 公共模塊,封裝配置類等
├── user # 業務模塊,包含啟動類、Mapper 接口
└── pom.xml
在 user
模塊中有如下啟動類:
@SpringBootApplication
@MapperScan("com.partner.user.mapper")
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class, args);}
}
在 common
模塊中配置了如下 MybatisPlusConfig
:
@Configuration
@EnableConfigurationProperties(MyBatisPlusProperties.class)
public class MybatisPlusConfig {@Beanpublic MapperScannerConfigurer mapperScannerConfigurer(MyBatisPlusProperties myBatisPlusProperties) {System.out.println("Mapper scan package: " + myBatisPlusProperties.getMapperScan());MapperScannerConfigurer configurer = new MapperScannerConfigurer();configurer.setBasePackage(myBatisPlusProperties.getMapperScan());return configurer;}
}
配置類依賴的配置文件如下(寫在 user
模塊的 bootstrap.yml
):
mybatis:mapperScan: com.partner.user.mapper
二、項目啟動失敗的根本原因
啟動失敗棧信息:
Caused by: java.lang.IllegalArgumentException: Property 'basePackage' is required
也就是說:MapperScannerConfigurer
沒有成功讀取到 basePackage
,傳入的是 null。從而導致 afterPropertiesSet()
拋出異常。
根本原因是:
MapperScannerConfigurer
是一個 Spring Bean,提前初始化,但它依賴的mybatis.mapperScan
配置卻定義在bootstrap.yml
中,屬于 Spring Cloud 的配置生命周期,尚未加載完成,導致值為null
。
三、常見誤區總結
錯誤實踐 | 原因 |
---|---|
配置 MapperScannerConfigurer 并從 bootstrap.yml 讀取 mapperScan | 配置未加載時就被調用,null 值引發異常 |
在多個模塊分別配置 mapper 掃描路徑 | 不同模塊配置加載順序不確定,容易互相覆蓋或無效 |
同時使用 @MapperScan 和 MapperScannerConfigurer | 存在重復掃描、不一致行為風險 |
四、推薦解決方案
? 推薦做法:只使用 @MapperScan
注解,徹底拋棄 MapperScannerConfigurer
這是最簡潔、最穩定的做法,推薦如下方式:
1. 在啟動類中添加注解:
@SpringBootApplication
@MapperScan("com.partner.user.mapper") // 替換為你自己的 mapper 包路徑
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class, args);}
}
2. 刪除 MapperScannerConfigurer
相關 Bean:
// ? 刪除該 Bean,否則仍然會因配置未加載而報錯
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(...) {...
}
這樣一來,MyBatis-Plus 會根據注解自動掃描 Mapper 接口,避免復雜配置和潛在異常。
五、其他可選做法(不推薦)
如果你確實有特殊需求,想動態配置掃描路徑,也應注意以下幾點:
-
配置寫在
application.yml
而非bootstrap.yml
,確保其生命周期早于 Bean 初始化; -
或使用 Spring Boot 2.2+ 的
@ConfigurationPropertiesScan
自動掃描配置類。
示例:
@ConfigurationProperties(prefix = "mybatis")
public class MyBatisPlusProperties {private String mapperScan;
}@Configuration
@ConfigurationPropertiesScan("com.partner.common.config")
public class MybatisPlusConfig {...
}
六、總結建議
方案 | 是否推薦 | 說明 |
---|---|---|
@MapperScan("xxx") 注解 | ? 推薦 | 簡單高效,避免生命周期問題 |
自定義配置類讀取掃描包路徑 | ? 不推薦 | 配置不易統一,生命周期難控制 |
多模塊共用一個配置類 + 注解掃描 | ? 推薦 | 公共模塊做分頁攔截器等配置,Mapper 掃描交給啟動類注解 |
七、寫在最后
在實際開發中,越是多模塊復雜項目,越應該避免不必要的配置項和手動掃描邏輯。優雅使用 @MapperScan
是最穩定的 MyBatis 配置方案。
如果你也遇到了類似的問題,希望這篇文章能幫你少走彎路!
📌如果本文對你有幫助,歡迎點贊、收藏、評論支持一下!
📮如有更多 Spring Boot 多模塊踩坑問題,歡迎留言交流~