spring整合 mybatis时 SqlSessionFactoryBean的一个小报错:Bean named ‘sqlSessionFactory‘ is expected to be of ty

简介: spring整合 mybatis时 SqlSessionFactoryBean的一个小报错:Bean named ‘sqlSessionFactory‘ is expected to be of ty

标题盛不下了,把报错写到这

Bean named 'sqlSessionFactory' is expected to be of type 'org.mybatis.spring.SqlSessionFactoryBean' but was actually of type 'org.apache.ibatis.session.defaults.DefaultSqlSessionFactory'

代码背景

只是在做spring整合mybatis 的练习的时候出现的一个报错,技术版本


spiring: 5.3.1

mybatis: 3.5.3

mybatis-spring(sping整合mybtis的jar): 2.0.6

aspectjweaver: 1.9.4

junit: 4.13.1

c3p0: 0.9.5.5

核心代码如下:

applicationContext.xml

<!-- 加载配置文件 -->
<context:property-placeholder location="jdbcConfig.properties"/>
<!-- 配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driver}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
<!-- 配置 Mybatis 的 Session 工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 数据库连接池 -->
    <property name="dataSource" ref="dataSource"/>
    <!-- 文件映射器 -->
    <property name="configLocation" value="classpath:mybatis-config.xml"/>
    <!-- 自动扫描 mapper.xml 文件 -->
    <property name="mapperLocations" value="classpath:com/krlin/mybatis/dao/*.xml"/>
</bean>

按照spring 的理解,这样就是在 spring 的 IOC 容器中 存了两个JAVA对象,一个是存放数据库配置数据的 dataSource ,一个是 mybatis 的 核心对象 sqlSessionFactory


按照常理,放在IOC 容器中的对象可以获取并使用,于是测试类中:

@Test
public void dataSourceTest() {
    /** 使用 ApplicationContext 接口, 获取 spring 容器 */
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    /** 根据 bean 的 id 获取对象 */
    ComboPooledDataSource dataSource = ac.getBean("dataSource", ComboPooledDataSource.class);
    System.out.println(dataSource.getJdbcUrl());
    System.out.println(dataSource.getUser());
    System.out.println(dataSource.getPassword());
}
@Test
public void SqlSessionFactoryTest() {
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    SqlSessionFactoryBean sqlSessionFactory = ac.getBean("sqlSessionFactory", SqlSessionFactoryBean.class);
    System.out.println(sqlSessionFactory);

代码分析

第一个 dataSource 的测试没有问题,第二个就报错了 Bean named 'sqlSessionFactory' is expected to be of type 'org.mybatis.spring.SqlSessionFactoryBean' but was actually of type 'org.apache.ibatis.session.defaults.DefaultSqlSessionFactory'

翻译一下也很简单, sqlSessionFactory 应该是 org.mybatis.spring.SqlSessionFactoryBean类型的,但是实际上却是 org.apache.ibatis.session.defaults.DefaultSqlSessionFactory 类型的。


心想不对啊,我在配置文件中提供的类就是 SqlSessionFactoryBean 没错啊,怎么会出现一个其他的类,进入 SqlSessionfactoryBean 发现

他实现了 FactoryBean<T> 接口,原来是当实现了这个接口的 Bean 放到 IOC容器的时候,那么容器中实际存放的其实就是 这个泛型T 的类型,这也就不难理解,我们需要的 SqlSessionFactory 是 SqlSessionFactoryBean 来提供的,因为 SqlSessionFactoryBean 实现的接口的泛型就是 sqlSessionFactory, 所以看似我们 放置了 SqlSessionFactoryBean, 但实际上在 IOC 中是一个 SqlSessionFactory罢了。


查看SqlSessionFactory 发现他是一个接口

他有两个实现类,而第一个实现类,就是放入到 IOC 里边的类型,所以我们在测试的时候,就会出现类型不匹配了。


解决办法也很简单,我们在测试类中,用 DefaultSqlSessionFactory 来接收就行了

@Test
public void SqlSessionFactoryTest() {
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    DefaultSqlSessionFactory sqlSessionFactory = ac.getBean("sqlSessionFactory", DefaultSqlSessionFactory.class);
    SysUserMapper mapper = sqlSessionFactory.openSession(true).getMapper(SysUserMapper.class);
    List<SysUserEntity> userList = mapper.getUserList();
    userList.forEach(System.out::println);
}

打印数据也没有问题(虽然我们平时也不这么用,但是逻辑上是可以同的)

代码本身没问题,就是自己的理解没有到位,没有看透 SqlSessionFactoryBean 背后的本质。

相关文章
|
10天前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
1月前
|
XML Java 数据格式
Spring从入门到入土(bean的一些子标签及注解的使用)
本文详细介绍了Spring框架中Bean的创建和使用,包括使用XML配置文件中的标签和注解来创建和管理Bean,以及如何通过构造器、Setter方法和属性注入来配置Bean。
66 9
Spring从入门到入土(bean的一些子标签及注解的使用)
|
28天前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
1月前
|
Java 关系型数据库 MySQL
springboot学习五:springboot整合Mybatis 连接 mysql数据库
这篇文章是关于如何使用Spring Boot整合MyBatis来连接MySQL数据库,并进行基本的增删改查操作的教程。
64 0
springboot学习五:springboot整合Mybatis 连接 mysql数据库
|
1月前
|
Java 数据库连接 API
springBoot:后端解决跨域&Mybatis-Plus&SwaggerUI&代码生成器 (四)
本文介绍了后端解决跨域问题的方法及Mybatis-Plus的配置与使用。首先通过创建`CorsConfig`类并设置相关参数来实现跨域请求处理。接着,详细描述了如何引入Mybatis-Plus插件,包括配置`MybatisPlusConfig`类、定义Mapper接口以及Service层。此外,还展示了如何配置分页查询功能,并引入SwaggerUI进行API文档生成。最后,提供了代码生成器的配置示例,帮助快速生成项目所需的基础代码。
|
1月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细解析Spring Bean的生命周期及其核心概念,并深入源码分析。Spring Bean是Spring框架的核心,由容器管理其生命周期。从实例化到销毁,共经历十个阶段,包括属性赋值、接口回调、初始化及销毁等。通过剖析`BeanFactory`、`ApplicationContext`等关键接口与类,帮助你深入了解Spring Bean的管理机制。希望本文能助你更好地掌握Spring Bean生命周期。
72 1
|
1月前
|
Java Spring
获取spring工厂中bean对象的两种方式
获取spring工厂中bean对象的两种方式
37 1
|
1月前
|
Java 数据库连接 Maven
Spring整合Mybatis
Spring整合Mybatis
|
5月前
|
Java 开发者 Spring
解析Spring中Bean的生命周期
解析Spring中Bean的生命周期
55 2
|
5月前
|
XML druid Java
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
62 0