在使用 MyBatis-Plus 进行数据库操作时,遇到以下问题:
@MapperScan
未正确加载 Mapper 类,@MapperScan
指定的Mapper包未被扫描,导致No mapper was found
错误。@PropertySource
中的配置文件未被解析。@Bean
声明的Bean未在Spring容器中注册,导致依赖注入失败。这个原因可能就是写的配置类没生效,下面详细讲讲
@SpringBootApplication
注解(包含@ComponentScan
)触发。@Configuration
的类,注册其@Bean
方法。@Component
、@Service
、@Repository
等注解的类,注册为Bean。@Import
注解:在配置类中直接导入其他配置类。spring.factories
文件:Spring Boot 2.6及以下版本的核心自动配置文件。AutoConfiguration.imports
文件:Spring Boot 2.7+引入的轻量级替代方案。Spring Boot启动时,会扫描META-INF/spring.factories
和META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件,加载声明的配置类。
@Configuration
注解@Bean
方法未被注册。// 错误示例:缺少 @Configuration
@EnableTransactionManagement
@MapperScan("com.example.mapper")
public class MyBatisConfig {
@Bean
public MybatisPlusInterceptor interceptor() { ... }
}
AutoConfiguration.imports
声明。AutoConfiguration.imports
中声明的类,无需依赖扫描路径。// 主启动类位于com.example包
@SpringBootApplication
public class Application {}
// 配置类位于com.example.config子包 → 可被扫描
@Configuration
public class MyConfig {}
// 配置类位于com.other包 → 无法被扫描
@Configuration
public class MyOtherConfig {}
@Configuration
注解通过 @Configuration
注解标记配置类,使 Spring Boot 能识别并加载其 @Bean
方法。
@Configuration
注解:
@Bean
方法转换为Bean定义。@ComponentScan
显式指定路径。@Configuration // 标记为配置类
@EnableTransactionManagement(proxyTargetClass = true)
@MapperScan("${mybatis-plus.mapperPackage}")
@PropertySource(value = "classpath:common-mybatis.yml", factory = YmlPropertySourceFactory.class)
public class MyBatisConfig {
// 配置拦截器、数据源等
}
@SpringBootApplication
@ComponentScan(basePackages = {"com.example.config"}) // 包含配置类的包路径
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Configuration
是配置类生效的必要条件。@ComponentScan
或 AutoConfiguration.imports
显式加载。AutoConfiguration.imports
文件通过 AutoConfiguration.imports
文件,强制 Spring Boot 加载指定的配置类,无需依赖组件扫描。
AutoConfiguration.imports
文件:
spring.factories
文件。AutoConfigurationImportSelector
解析文件内容,生成Bean定义。在项目资源目录下创建路径:
src/main/resources/
└── META-INF/
└── spring/
└── org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件内容为配置类的全限定名,每行一个:
# 示例:加载 MyBatis 配置类
com.example.config.MyBatisConfig
# 其他配置类(可选)
com.example.config.OtherConfig
确保文件路径正确,且无拼写错误(如 META-INF/spring
而非 META-INF/spring.factories
)。
META-INF/spring
目录下。spring.factories
。方案 | 适用场景 | 优势 | 限制 |
---|---|---|---|
@Configuration |
单模块项目,配置类位于主包路径下 | 简单直接,无需额外文件 | 依赖组件扫描路径,多模块时可能冲突 |
AutoConfiguration.imports |
多模块项目、第三方库、配置类需独立加载 | 解耦模块,无需修改组件扫描路径 | 需手动创建文件,文件路径需严格符合规范 |
在复杂项目中,可结合两者:
@Configuration // 标记配置类
public class MyBatisConfig { ... }
同时在 AutoConfiguration.imports
中声明:
com.example.config.MyBatisConfig
META-INF/spring.factories
:传统自动配置文件。META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
:新机制。AutoConfiguration.imports
中的类名,加载对应的配置类。@Configuration
类中的 @Bean
方法,注册到 Spring 容器。AutoConfiguration.imports
的底层实现spring.factories
更高效,仅加载声明的类。SpringFactoriesLoader
加载文件中的类,并调用 @Configuration
的 @Bean
方法。AutoConfiguration.imports
中声明所有公共配置类。@Configuration
标记本地配置类,或在父模块中统一声明。<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.5.3version>
dependency>
dependencies>
dependencyManagement>
AutoConfiguration.imports
,声明配置类:com.parentmodule.config.MybatisPlusConfig
通过@ConditionalOnProperty
实现条件化加载:
@Configuration
@ConditionalOnProperty(prefix = "mybatis-plus", name = "enabled", havingValue = "true")
public class MybatisPlusConfig {
// 配置内容
}
META-INF/spring
目录中提供 AutoConfiguration.imports
。@Configuration
或文件路径错误。META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
。ClassNotFoundException
。启动日志应包含以下信息:
Loading configuration class 'com.yourpackage.config.MybatisPlusConfig'
在任意@Service
或@Component
中注入配置的Bean:
@Autowired
private MybatisPlusInterceptor interceptor;
@PostConstruct
public void init() {
System.out.println("Interceptor: " + interceptor);
}
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;
}
}
# src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.example.config.MyBatisConfig
Application.java
)@SpringBootApplication
@ComponentScan(basePackages = {"com.example"}) // 可选:显式指定扫描路径
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Configuration
是配置类生效的基础,必须添加。AutoConfiguration.imports
是加载配置类的机制,适用于复杂项目。维度 | @Configuration | AutoConfiguration.imports |
---|---|---|
加载机制 | 依赖组件扫描路径 | 无需扫描,直接声明加载 |
适用场景 | 单模块、路径简单 | 多模块、第三方JAR、复杂路径 |
性能 | 可能受组件扫描路径影响 | 更高效,仅加载声明的类 |
依赖关系 | 需确保依赖的Bean已注册 | 需确保依赖的Bean已通过其他方式注册 |
代码侵入性 | 需修改配置类代码 | 无需修改代码,仅需文件声明 |
选择建议:
spring.factories
。AutoConfiguration.imports
,但兼容spring.factories
。spring.factories
的自动配置功能。扩展阅读:
通过本文的详细讲解,相信读者已能深刻理解配置未生效的原因,并能灵活运用两种解决方案。如果仍有疑问,欢迎在评论区讨论!