MyBatis-Plus配置未生效的問題及解決
一、問題背景
在使用 MyBatis-Plus 進(jìn)行數(shù)據(jù)庫操作時(shí),遇到以下問題:
- SQL 語句未生效:分頁、樂觀鎖、數(shù)據(jù)權(quán)限等插件未起作用。
- Mapper 接口未掃描:
@MapperScan未正確加載 Mapper 類,@MapperScan指定的Mapper包未被掃描,導(dǎo)致No mapper was found錯(cuò)誤。 - 屬性未注入:
@PropertySource中的配置文件未被解析。 - Bean未注冊:通過
@Bean聲明的Bean未在Spring容器中注冊,導(dǎo)致依賴注入失敗。
這個(gè)原因可能就是寫的配置類沒生效,下面詳細(xì)講講
二、問題根源分析
1. Spring Boot 的配置類加載機(jī)制
(1)組件掃描(Component Scanning)
觸發(fā)條件:默認(rèn)由@SpringBootApplication注解(包含@ComponentScan)觸發(fā)。
掃描范圍:默認(rèn)掃描主啟動類的同包及子包。
識別規(guī)則:
- 掃描到帶有
@Configuration的類,注冊其@Bean方法。 - 掃描到
@Component、@Service、@Repository等注解的類,注冊為Bean。
(2)顯式聲明(Explicit Declaration)
@Import注解:在配置類中直接導(dǎo)入其他配置類。spring.factories文件:Spring Boot 2.6及以下版本的核心自動配置文件。AutoConfiguration.imports文件:Spring Boot 2.7+引入的輕量級替代方案。
(3)類路徑掃描
Spring Boot啟動時(shí),會掃描META-INF/spring.factories和META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,加載聲明的配置類。
2. 問題產(chǎn)生的關(guān)鍵原因
(1) 缺少@Configuration注解
問題:配置類未被 Spring 識別為配置類,導(dǎo)致其 @Bean 方法未被注冊。
示例:
// 錯(cuò)誤示例:缺少 @Configuration
@EnableTransactionManagement
@MapperScan("com.example.mapper")
public class MyBatisConfig {
@Bean
public MybatisPlusInterceptor interceptor() { ... }
}
(2) 配置類未被自動加載
- 問題:配置類不在組件掃描路徑,且未通過
AutoConfiguration.imports聲明。 - 場景:多模塊項(xiàng)目中,配置類位于獨(dú)立模塊或第三方 JAR 包中。
- 關(guān)鍵點(diǎn):Spring Boot優(yōu)先加載
AutoConfiguration.imports中聲明的類,無需依賴掃描路徑。
(3) 未被組件掃描覆蓋
問題:配置類位于主啟動類的非掃描路徑下,導(dǎo)致Spring無法發(fā)現(xiàn)該類。
示例:
// 主啟動類位于com.example包
@SpringBootApplication
public class Application {}
// 配置類位于com.example.config子包 → 可被掃描
@Configuration
public class MyConfig {}
// 配置類位于com.other包 → 無法被掃描
@Configuration
public class MyOtherConfig {}
三、解決方案一:添加@Configuration注解
1. 解決思路
通過 @Configuration 注解標(biāo)記配置類,使 Spring Boot 能識別并加載其 @Bean 方法。
2. 核心原理
@Configuration注解:
- 標(biāo)記該類為配置類,Spring會將其
@Bean方法轉(zhuǎn)換為Bean定義。 - 觸發(fā)Spring的CGLIB代理,生成配置類的代理對象。
組件掃描機(jī)制:
- 配置類需位于Spring的組件掃描路徑下,或通過
@ComponentScan顯式指定路徑。
3. 實(shí)現(xiàn)步驟
(1) 添加注解
@Configuration // 標(biāo)記為配置類
@EnableTransactionManagement(proxyTargetClass = true)
@MapperScan("${mybatis-plus.mapperPackage}")
@PropertySource(value = "classpath:common-mybatis.yml", factory = YmlPropertySourceFactory.class)
public class MyBatisConfig {
// 配置攔截器、數(shù)據(jù)源等
}
(2) 確保組件掃描路徑
方式1:配置類位于主啟動類的同包或子包中。
方式2:顯式指定掃描路徑:
@SpringBootApplication
@ComponentScan(basePackages = {"com.example.config"}) // 包含配置類的包路徑
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
4. 規(guī)范與注意事項(xiàng)
- 必須添加:
@Configuration是配置類生效的必要條件。 - 組件掃描范圍:若配置類在獨(dú)立模塊或第三方庫中,需通過
@ComponentScan或AutoConfiguration.imports顯式加載。
四、解決方案二:使用AutoConfiguration.imports文件
1. 解決思路
通過 AutoConfiguration.imports 文件,強(qiáng)制 Spring Boot 加載指定的配置類,無需依賴組件掃描。
2. 核心原理
AutoConfiguration.imports文件:
- 作用:直接聲明需要加載的配置類,無需依賴組件掃描路徑。
- 優(yōu)先級:Spring Boot 3.0+中優(yōu)先于
spring.factories文件。 - 實(shí)現(xiàn)機(jī)制:通過
AutoConfigurationImportSelector解析文件內(nèi)容,生成Bean定義。
3. 實(shí)現(xiàn)步驟
(1) 創(chuàng)建文件
在項(xiàng)目資源目錄下創(chuàng)建路徑:
src/main/resources/
└── META-INF/
└── spring/
└── org.springframework.boot.autoconfigure.AutoConfiguration.imports
(2) 填寫內(nèi)容
文件內(nèi)容為配置類的全限定名,每行一個(gè):
# 示例:加載 MyBatis 配置類 com.example.config.MyBatisConfig # 其他配置類(可選) com.example.config.OtherConfig
(3) 驗(yàn)證文件路徑
確保文件路徑正確,且無拼寫錯(cuò)誤(如 META-INF/spring 而非 META-INF/spring.factories)。
4. 規(guī)范與注意事項(xiàng)
- 文件路徑:必須位于
META-INF/spring目錄下。 - 類名格式:必須使用全限定名(包名+類名)。
- 版本要求:Spring Boot 2.7+ 支持此功能,舊版本需使用
spring.factories。
五、兩種方案的對比與選擇
| 方案 | 適用場景 | 優(yōu)勢 | 限制 |
|---|---|---|---|
| @Configuration | 單模塊項(xiàng)目,配置類位于主包路徑下 | 簡單直接,無需額外文件 | 依賴組件掃描路徑,多模塊時(shí)可能沖突 |
| AutoConfiguration.imports | 多模塊項(xiàng)目、第三方庫、配置類需獨(dú)立加載 | 解耦模塊,無需修改組件掃描路徑 | 需手動創(chuàng)建文件,文件路徑需嚴(yán)格符合規(guī)范 |
1. 組合使用場景
在復(fù)雜項(xiàng)目中,可結(jié)合兩者:
@Configuration // 標(biāo)記配置類
public class MyBatisConfig { ... }
同時(shí)在 AutoConfiguration.imports 中聲明:
com.example.config.MyBatisConfig
六、原理深入:Spring Boot 的自動配置機(jī)制
1. 自動配置流程
啟動階段:Spring Boot 會掃描以下資源:
META-INF/spring.factories:傳統(tǒng)自動配置文件。META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:新機(jī)制。
加載配置類:根據(jù) AutoConfiguration.imports 中的類名,加載對應(yīng)的配置類。
注冊 Bean:解析 @Configuration 類中的 @Bean 方法,注冊到 Spring 容器。
2.AutoConfiguration.imports的底層實(shí)現(xiàn)
- 優(yōu)先級:比
spring.factories更高效,僅加載聲明的類。 - 機(jī)制:通過
SpringFactoriesLoader加載文件中的類,并調(diào)用@Configuration的@Bean方法。
七、常見問題
1. 最佳實(shí)踐
(1) 多模塊項(xiàng)目配置
- 主模塊:在
AutoConfiguration.imports中聲明所有公共配置類。 - 子模塊:通過
@Configuration標(biāo)記本地配置類,或在父模塊中統(tǒng)一聲明。
步驟
在父POM中統(tǒng)一管理依賴:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
</dependencies>
</dependencyManagement>
在配置模塊中創(chuàng)建AutoConfiguration.imports,聲明配置類:
com.parentmodule.config.MybatisPlusConfig
2. 結(jié)合條件注解的動態(tài)配置
通過@ConditionalOnProperty實(shí)現(xiàn)條件化加載:
@Configuration
@ConditionalOnProperty(prefix = "mybatis-plus", name = "enabled", havingValue = "true")
public class MybatisPlusConfig {
// 配置內(nèi)容
}
(2) 第三方庫集成
- JAR 包提供者:在 JAR 的
META-INF/spring目錄中提供AutoConfiguration.imports。 - 用戶端:無需額外配置,直接引入依賴即可生效。
2. 常見問題與解決
(1) 配置類未生效
- 原因:缺少
@Configuration或文件路徑錯(cuò)誤。 - 解決:檢查注解和文件路徑,確保類名與包路徑一致。
(2) 文件路徑錯(cuò)誤
- 癥狀:日志未輸出配置類加載信息。
- 解決:確保路徑為
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports。
(3) 類名拼寫錯(cuò)誤
- 癥狀:啟動時(shí)拋出
ClassNotFoundException。 - 解決:檢查文件中的類名是否與實(shí)際包路徑完全匹配。
3. 驗(yàn)證配置是否生效
方法1:日志檢查
啟動日志應(yīng)包含以下信息:
Loading configuration class 'com.yourpackage.config.MybatisPlusConfig'
方法2:測試Bean注冊
在任意@Service或@Component中注入配置的Bean:
@Autowired
private MybatisPlusInterceptor interceptor;
@PostConstruct
public void init() {
System.out.println("Interceptor: " + interceptor);
}
八、完整示例代碼
1. 配置類(MyBatisConfig.java)
@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
@MapperScan("${mybatis-plus.mapperPackage}")
@PropertySource(value = "classpath:common-mybatis.yml", factory = YmlPropertySourceFactory.class)
public class MyBatisConfig {
@Bean
public MybatisPlusInterceptor interceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
2. AutoConfiguration.imports 文件
# src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports com.example.config.MyBatisConfig
3. 啟動類(Application.java)
@SpringBootApplication
@ComponentScan(basePackages = {"com.example"}) // 可選:顯式指定掃描路徑
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
九、總結(jié)
@Configuration 是配置類生效的基礎(chǔ),必須添加。
AutoConfiguration.imports 是加載配置類的機(jī)制,適用于復(fù)雜項(xiàng)目。
組合使用兩者 可以平衡靈活性與解耦性,適應(yīng)不同場景。
- 方案一:適合單模塊、路徑簡單的項(xiàng)目。
- 方案二:適合多模塊、復(fù)雜路徑或第三方庫的自動配置。
| 維度 | @Configuration | AutoConfiguration.imports |
|---|---|---|
| 加載機(jī)制 | 依賴組件掃描路徑 | 無需掃描,直接聲明加載 |
| 適用場景 | 單模塊、路徑簡單 | 多模塊、第三方JAR、復(fù)雜路徑 |
| 性能 | 可能受組件掃描路徑影響 | 更高效,僅加載聲明的類 |
| 依賴關(guān)系 | 需確保依賴的Bean已注冊 | 需確保依賴的Bean已通過其他方式注冊 |
| 代碼侵入性 | 需修改配置類代碼 | 無需修改代碼,僅需文件聲明 |
選擇建議:
- 優(yōu)先方案一:若配置類位于主包路徑,且項(xiàng)目結(jié)構(gòu)簡單。
- 優(yōu)先方案二:若項(xiàng)目為多模塊或需避免組件掃描范圍沖突。
Spring Boot版本兼容性
- Spring Boot 2.6及以下:僅支持
spring.factories。 - Spring Boot 2.7+:支持
AutoConfiguration.imports,但兼容spring.factories。 - Spring Boot 3.0+:完全棄用
spring.factories的自動配置功能。
擴(kuò)展閱讀:
通過本文的詳細(xì)講解,相信讀者已能深刻理解配置未生效的原因,并能靈活運(yùn)用兩種解決方案。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)2048小游戲(可直接運(yùn)行)
這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)2048小游戲的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
使用Jackson進(jìn)行JSON生成與解析的新手指南
這篇文章主要為大家詳細(xì)介紹了如何使用Jackson進(jìn)行JSON生成與解析處理,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-04-04
使用IntelliJ IDEA2020.2.2 x64 新建java項(xiàng)目并且輸出Hello World
這篇文章主要介紹了使用IntelliJ IDEA2020.2.2 x64 新建java項(xiàng)目并且輸出Hello World,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
Java利用for循環(huán)輸出空心菱形的實(shí)例代碼
這篇文章主要介紹了Java利用for循環(huán)輸出空心菱形的實(shí)例代碼,需要的朋友可以參考下2014-02-02

