Spring整合Mybatis时,项目启动时报错:(MapperScannerConfigurer之sqlSessionFactoryBeanName注入方式)

  1. pringframework.beans.factory.BeanCreationException: Error creating bean with name 'mapperScannerConfigurer'defined in class path resource [applicationContext.xml]:
  2. Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sqlSessionFactory';
  3. nested exception is org.springframework.beans.factory BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xml]:
  4. Cannot resolve reference to bean
  5. 'dataSource' while setting bean property 'dataSource';
  6. nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [applicationContext.xml]: Error setting property values;
  7. nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are: PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'driverClassName' threw exception;
  8. nested exception is java.lang.IllegalStateException: Could not load JDBC driver class [${driver}]

可以看到报的大大小小错误共有5个错误:

pringframework.beans.factory.BeanCreationException:创建名为“mapperScannerConfigurer”的bean时出错,该bean在类路径资源[applicationContext.xml]中定义:

设置bean属性“sqlSessionFactory”时无法解析对bean“sessionFactory”的引用;

嵌套异常为org.springframework.beans.factory BeanCreationException:创建名为“sessionFactory”的bean时出错,该bean在类路径资源[applicationContext.xml]中定义:

无法解析对bean的引用

设置bean属性“dataSource”时使用“dataSource”;

嵌套异常为org.springframework.beans.factory.BeanCreationException:创建名为“dataSource”的bean时出错,该bean在类路径资源[applicationContext.xml]中定义:设置属性值时出错;

嵌套的异常是org.springframework.beans.PropertyBatchUpdateException;嵌套的PropertyAccessException(1)是:PropertyAccessException 1:org.springframework.beans.MethodInvocationException:Property'driverClassName'抛出异常;

嵌套异常为java.lang.IllegalStateException:无法加载JDBC驱动程序类[${driver}]

ok,那么下面是我的Spring配置文件的源代码

  1. <context:property-placeholder location="classpath:/jdbc.properties"/>
  2. <!-- 配置数据源bean -->
  3. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  4. <property name="driverClassName" value="${driver}"/>
  5. <property name="url" value="${url}"/>
  6. <property name="password" value="${password}"/>
  7. <property name="username" value="${user}"/>
  8. </bean>
  9. <!-- SqlSessionFactory的bean -->
  10. <bean name="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  11. <property name="dataSource" ref="dataSource"/>
  12. </bean>
  13. <!-- 扫描Mapper文件 -->
  14. <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  15. <property name="sqlSessionFactory" ref="sessionFactory"/>
  16. <property name="basePackage" value="com.lyl.mapper"/>
  17. </bean>

通过分析日志提供的报错信息,发现跟本的原因时因为程序没有加载JDBC的驱动,也就是数据源bean中的driverClassName没有加载成功,因为我这里采用的是jdbc.properties的方式来加载数据源参数信息,所有我一开是怀疑的是文件的驱动路径写错了或者jdbc的包没有导入环境中,但是折腾后面发现一切正常,于是索性的将${driver}直接替换成文件中的参数,引入改成手写,启动项目,竟然发现启动成功!,这让我百思不得其解,于是开始漫长的百度,找不到我想要的答案,便再看一遍日志,发现是因为配置sqlSessionFactorybean时,dataSource出错找不到JDBC驱动,既然JDBC驱动没有毛病,sqlSessionFactory也不可能出毛病,于是我就将目光锁定到了mapperScannerConfigurerbean,因为他注入了没有毛病的SQL Session Factory,然后就是开始百度,果然,找对了错误答案一下就出来了。

原来的mapperScannerConfigurerbean:

  1. <!-- 扫描Mapper文件 -->
  2. <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  3. <property name="sqlSessionFactory" ref="sessionFactory"/>
  4. <property name="basePackage" value="com.lyl.mapper"/>
  5. </bean>

修改后的mapperScannerConfigurerbean:

  1. <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  2. <property name="sqlSessionFactoryBeanName" value="sessionFactory"/>
  3. <!-- <property name="sqlSessionFactory" ref="sessionFactory"/>-->
  4. <property name="basePackage" value="com.lyl.mapper"/>
  5. </bean>

可以发现,不再注入sqlSessionFactory的属性,取而代之的是sqlSessionFactoryBeanName属性,并且用的是value来赋值,程序能够正常run。

那么问题是解决了,原理是什么呢?我又百度了sqlSessionFactoryBeanName这的个属性。

发现在MapperScannerConfigurer中有4种注入方式,而sqlSessionFactory的注入方式已经过时了,而造成本次报错的根本原因出现在MapperScannerConfigurer上:

在mybatis-spring1.1.0之前,是经过将SqlSessionFactory对象注入到sqlSessionFactory,这样作可能会有一个问题,就是在初始化MyBatis时,jdbc.properties文件还没被加载进来,dataSource的属性值没有被替换,就开始构造sqlSessionFactory类,属性值就会加载失败。在1.1.0之后,MapperScannerConfigure提供了String类型的sqlSessionFactoryBeanName,这样将bean name注入到sqlSessionFactoryBeanName,这样就会等到spring初始化完成后,再构建sqlSessionFactory。

终于找到了错误本质了,折腾了大半天!发现原来是jdbc.properties文件和SqlSessionFactory出现了冲突,在MapperScannerConfigurer中直接注入sqlSessionFactory属性,如果使用的是占位符去配置dataSourcebean,那么可能会造成sqlSessionFactory构建先于jdbc.properties文件的加载。

目前还没有找到用sqlSessionFactory来注入成功的解决方法(除非直接写jdbc的值不用占位符形式),既然都过时了那就不用了吧。

MapperScannerConfigurer之sqlSessionFactoryBeanName注入方式的更多相关文章

  1. spring四种依赖注入方式

    一.Set注入 这是最简单的注入方式,假设有一个SpringAction,类中需要实例化一个SpringDao对象,那么就可以定义一个private的SpringDao成员变量,然后创建SpringD ...

  2. Spring的三种通过XML实现DataSource注入方式

    Spring的三种通过XML实现DataSource注入方式: 1.使用Spring自带的DriverManagerDataSource 2.使用DBCP连接池 3.使用Tomcat提供的JNDI

  3. spring笔记--依赖注入之针对不同类型变量的几种注入方式

    控制反转和依赖注入讲的都是一个概念,只不过是站在了不同的角度,所谓的依赖注入: 是指在运行期,由外部容器动态地将依赖对象注入到组件中.当spring容器启动后,spring容器初始化,创建并管理bea ...

  4. 控制反转IOC的依赖注入方式

    引言: 项目中遇到关于IOC的一些内容,因为和正常的逻辑代码比较起来,IOC有点反常.因此本文记录IOC的一些基础知识,并附有相应的简单实例,而在实际项目中再复杂的应用也只是在基本应用的基础上扩展而来 ...

  5. spring ioc三种注入方式

    spring ioc三种注入方式 IOC ,全称 (Inverse Of Control) ,中文意思为:控制反转 什么是控制反转? 控制反转是一种将组件依赖关系的创建和管理置于程序外部的技术. 由容 ...

  6. spring 学习之 bean 的注入方式 property和constructor-arg的使用方式

    spring 学习之 bean 的注入方式 property和constructor-arg的使用方式. bean的注入方式: property 注入是: 通过setxx方法注入. construct ...

  7. Spring IOC 注入方式

    依赖注入通常有如下两种方式: ①设值注入:IOC容器使用属性的Setter方法来注入被依赖的实例. 设值注入是指IOC容器使用属性的Setter方法来注入被依赖的实例.这种注入方式简单.直观,因而在S ...

  8. Spring 3种注入方式

    spring的三种注入方式: 接口注入(不推荐) getter,setter方式注入(比较常用) 构造器注入(死的应用) 关于getter和setter方式的注入: autowire="de ...

  9. Spring 依赖注入方式详解

    平常的Java开发中,程序员在某个类中需要依赖其它类的方法. 通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理. Spring提出了依赖注入的思想,即依赖类不由 ...

随机推荐

  1. 大数据学习(02)——HDFS入门

    Hadoop模块 提到大数据,Hadoop是一个绕不开的话题,我们来看看Hadoop本身包含哪些模块. Common是基础模块,这个是必须用的.剩下常用的就是HDFS和YARN. MapReduce现 ...

  2. noip模拟测试31

    终于有时间写博客了,前面一直咕咕咕都快变成一只公鸡了......这次考试,真的很意外,我在考场上觉得自己打出了T1的正解,样例一拍就过,还跑得嘎嘎快,然后T2,T3码了两个暴力,觉得自己应该能100p ...

  3. C 购买商品的游戏

    1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 /* 5 *模拟实现道具店购物 ...

  4. GitHub标星8k,字节跳动高工熬夜半月整理的“组件化实战学习手册”,全是精髓!

    前言 什么是组件化? 最初的目的是代码重用,功能相对单一或者独立.在整个系统的代码层次上位于最底层,被其他代码所依赖,所以说组件化是纵向分层. 为什么要使用组件化? 当我们的项目越做越大的时候,有时间 ...

  5. Microservices==>Service Mesh==>Serverless,走马观花

    [0] 始有道 话说图灵开天辟地,冯.诺伊曼造石补天! 始有道道生ML Machine LanguageML生汇编 assembler汇编生编译器 compiler编译器生PL Programming ...

  6. git submodule 操作

    git submodule foreach git status 举一反三,对所有子库的操作,都可以使用 git submodule foreach 做前缀 foreach,可以记忆为for each ...

  7. 《手把手教你》系列技巧篇(十八)-java+ selenium自动化测试-元素定位大法之By css中卷(详细教程)

    1.简介 按计划今天宏哥继续讲解倚天剑-css的定位元素的方法:ID属性值定位.其他属性值定位和使用属性值的一部分定位(这个类似xpath的模糊定位). 2.常用定位方法(8种) (1)id(2)na ...

  8. shell趣味实验——图形

    目录 一.直线 二.矩形 2.1.镂空矩形 三.直角三角形 3.1.倒直角三角形 3.2.反直角三角形 3.3.等腰三角形 3.4.倒等腰三角形 3.5.菱形 四.平行四边形 五.梯形 5.1.等腰梯 ...

  9. linux service脚本

    vim /etc/systemd/system/node_exporter.service [Unit] Description=node_exporter Documentation=https:/ ...

  10. 网络安全学习阶段性总结:SQL注入|SSRF攻击|OS命令注入|身份验证漏洞|事物逻辑漏洞|目录遍历漏洞

    目录 SQL注入 什么是SQL注入? 掌握SQL注入之前需要了解的知识点 SQL注入情况流程分析 有完整的回显报错(最简单的情况)--检索数据: 在HTTP报文中利用注释---危险操作 检索隐藏数据: ...