Java IllegalArgumentException: Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required问题解决
'# Java IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required问题解决
一、背景与问题
在基于Spring Boot的MyBatis项目中,开发人员常常会遇到以下异常:
java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required这个错误通常出现在以下场景中:
- 在Spring Boot项目中未正确配置MyBatis
- 在XML配置文件中遗漏了关键属性
- 在使用注解配置时未正确声明Bean
- 在多数据源环境中配置错误
这个问题的根源在于Spring和MyBatis的整合机制中,SqlSessionFactory和SqlSessionTemplate作为核心组件,其创建过程需要依赖特定的配置参数。当这些参数未被正确提供时,Spring会抛出上述异常。
二、基本原理
MyBatis与Spring的整合本质上是通过BeanPostProcessor实现的。当Spring容器启动时,会通过以下流程处理MyBatis配置:
- 读取配置文件中的MyBatis配置
- 创建SqlSessionFactory(通过SqlSessionFactoryBean)
- 创建SqlSessionTemplate(通过SqlSessionTemplate)
- 注入到Mapper接口中
关键点在于:
- SqlSessionFactory需要配置dataSource、mapperLocations等属性
- SqlSessionTemplate需要配置sqlSessionFactory和executorType等属性
- 这些配置参数必须通过Spring的配置机制传递
三、环境准备
我们使用Spring Boot 2.7 + MyBatis 2.2.2的环境:
<!-- pom.xml -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
</dependencies>四、核心实现
1. XML配置方式
@Configuration
public class MyBatisConfig {
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:mapper/*.xml"));
return factory.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}关键点:
- 必须显式声明这两个Bean
- 需要通过setter方法传递参数
- 需要处理异常
2. 注解配置方式
@Configuration
@MapperScan("com.example.mapper")
public class MyBatisConfig {
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:mapper/*.xml"));
return factory.getObject();
}
}3. Spring Boot自动配置
# application.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath*:mapper/*.xml五、完整案例
创建一个完整的Spring Boot项目:
实体类:
@Entity public class User { @Id private Long id; private String name; // getters and setters }Mapper接口:
@Mapper public interface UserMapper { User selectById(Long id); }配置类:
@Configuration @MapperScan("com.example.mapper") public class MyBatisConfig { @Bean public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); factory.setDataSource(dataSource); factory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources("classpath*:mapper/*.xml")); return factory.getObject(); } }启动类:
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
完整案例说明:
- 使用@MapperScan自动注册Mapper接口
- 通过SqlSessionFactoryBean创建SqlSessionFactory
- 自动注入到Mapper接口中
- 无需显式声明SqlSessionTemplate
六、源码解析
在Spring Boot的自动配置中,关键代码如下:
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionTemplate.class})
@ConditionalOnMissingBean({SqlSessionFactory.class, SqlSessionTemplate.class})
public class MyBatisAutoConfiguration {
// 自动配置逻辑
}关键点:
- 通过@ConditionalOnClass确保依赖存在
- 通过@ConditionalOnMissingBean确保未显式配置时自动创建
- 使用BeanPostProcessor进行后处理
七、进阶使用
多数据源配置
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public DataSource routingDataSource(DataSource primary, DataSource secondary) {
AbstractRoutingDataSource routingDataSource = new AbstractRoutingDataSource();
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("primary", primary);
targetDataSources.put("secondary", secondary);
routingDataSource.setDefaultTargetDataSource(primary);
routingDataSource.setTargetDataSources(targetDataSources);
return routingDataSource;
}
}自定义SqlSessionFactory
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setConfiguration(new Configuration());
factory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:mapper/*.xml"));
return factory.getObject();
}八、性能与工程实践
性能优化建议
使用连接池配置:
spring: datasource: url: jdbc:mysql://localhost:3306/mydb username: root password: password driver-class-name: com.mysql.cj.jdbc.Driver hikari: maximum-pool-size: 20启用MyBatis缓存:
<cache></cache>- 避免频繁创建SqlSessionTemplate
安全注意事项
- 配置文件中避免直接暴露敏感信息
- 使用加密配置项(如Vault)
- 避免将数据库密码硬编码在代码中
九、常见问题与踩坑
1. 配置遗漏
// 错误示例
@Bean
public SqlSessionFactory sqlSessionFactory() {
return new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
}问题:未指定DataSource,导致创建的SqlSessionFactory无效
2. 版本兼容性问题
// 错误示例
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
return factory.getObject();
}问题:MyBatis 3.5+版本需要显式设置mapperLocations
3. 多数据源配置错误
// 错误示例
@Bean
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}问题:未配置多数据源时,会创建单一数据源
十、最佳实践
推荐方案
- 使用Spring Boot自动配置(推荐)
- 在需要自定义配置时使用@MapperScan
- 对于多数据源场景,使用AbstractRoutingDataSource
- 使用HikariCP作为连接池
- 对于复杂配置,使用XML文件管理
避免使用的情况
- 不需要自定义配置时,不要显式声明Bean
- 不要在单数据源场景中使用复杂的配置
- 避免在配置中硬编码敏感信息
十一、总结
Java的IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required问题本质上是Spring与MyBatis整合过程中的配置问题。通过深入理解其工作原理,我们可以更有效地进行配置管理。
在实际开发中,建议:
- 使用Spring Boot的自动配置简化配置
- 在需要自定义配置时,使用@MapperScan和SqlSessionFactoryBean
- 对于多数据源场景,使用AbstractRoutingDataSource
- 始终保持配置的简洁性和可维护性
通过合理配置和深入理解底层原理,可以有效避免这类问题,同时提升系统的稳定性和可维护性。在复杂的业务场景中,正确的配置是保证系统正常运行的关键基础。
评论已关闭