在使用 Spring Boot 与 MyBatis 进行项目开发时,可能会遇到 BeanCreationException 错误,特别是在创建 sqlSessionFactory Bean 时。本文将详细探讨这一问题的可能原因,并重点介绍如何通过 YAML 配置文件解决此问题。
一、问题描述
当尝试启动 Spring Boot 应用时,控制台输出如下异常信息:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception with message: Could not open ServletContext resource [/src/main/resources/mapper/**.xml]
该异常表明,在创建 sqlSessionFactory Bean 的过程中,MyBatis 未能成功加载位于 /src/main/resources/mapper/ 下的 XML 映射文件。
二、原因分析
-
资源路径配置错误
MyBatis 默认会从类路径下加载 Mapper XML 文件,但开发者在配置时可能指定了错误的路径格式,例如使用了绝对路径(如 /src/main/resources/mapper/*.xml),而不是相对类路径的路径。 -
使用 properties 格式配置出错
在 application.properties 文件中,配置项较为简单,但有时容易出现格式或路径书写错误。例如:
mybatis.mapper-locations=classpath:mapper/*.xml
如果路径未正确解析,可能会导致资源加载失败。
3. YAML 配置的优势
相比之下,application.yml 的层级结构更清晰,能够更直观地表达复杂的配置项,减少因格式错误导致的问题。
三、解决方案
- 使用 application.yml 配置 mapper-locations
在 application.yml 文件中,明确指定 Mapper XML 文件的位置。以下是一个示例配置:
mybatis:
mapper-locations: classpath:mapper/*.xml
这里的 classpath: 前缀表示从类路径中加载资源,而不是从文件系统路径
2. 确保 XML 文件被正确打包
确保 Mapper XML 文件位于 src/main/resources/mapper/ 目录下,并且构建工具(如 Maven 或 Gradle)已将其包含到最终的 JAR 或 WAR 包中。
Maven 配置
检查 pom.xml 文件,确保资源目录被正确包含:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
Gradle 配置
检查 build.gradle 文件,确保资源目录被正确包含:
sourceSets {
main {
resources {
srcDirs = ['src/main/resources']
include '**/*.xml'
}
}
}
- 检查 @MapperScan 注解配置
如果您在代码中使用了 @MapperScan 注解,请确保扫描的包路径与 Mapper 接口所在的包一致。例如:
@MapperScan("com.example.mapper")
- 验证配置是否生效
完成上述修改后,重新启动应用程序并观察是否仍然报错。如果问题解决,则说明 YAML 配置已生效;如果问题仍然存在,请检查以下内容: - 是否有其他依赖冲突。
- 是否遗漏了某些必要的配置。
四、为什么 YAML 更适合?
相比于 properties 文件,YAML 文件具有以下优势:
- 层级结构清晰:YAML 使用缩进表示层级关系,非常适合复杂配置。
- 可读性更强:YAML 的语法更接近自然语言,易于阅读和维护。
- 避免格式错误:YAML 对空格和缩进敏感,虽然需要严格遵守格式,但也减少了因格式混乱导致的错误。