org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.mybatis.spring.mapper.MapperScannerConfigurer#0' defined in file [xxx\applicationContext-mybatis.xml]: Cannot resolve reference to bean 'sqlSessionFactory' while setting bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in file [xxx\applicationContext-mybatis.xml]: Cannot resolve reference to bean 'dataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in file [xxx\applicationContext-mybatis.xml]: Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'driverClassName' threw exception; nested exception is java.lang.IllegalStateException: Could not load JDBC driver class [${jdbc.driver}]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1469)
首先,我把異常定位到Property 'driverClassName' threw exception; nested exception is java.lang.IllegalStateException: Could not load JDBC driver class [${jdbc.driver}]
信息上,這個異常我一開始一直以爲${jdbc.driver}的值是獲取到了,可能是驅動jar包之類的原因導致jdbc沒加載成功,所以我查了下項目的Libraries,發現裏面有mysql-connector-java的依賴。然後,我就將driverClassName的值改爲com.mysql.jdbc.Driver,項目部署沒有報錯。
可是,當我使用mapper操作數據庫時,又出現了錯誤,報錯信息如下:
Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: No suitable driver found for ${jdbc.url}] with root cause
java.sql.SQLException: No suitable driver found for ${jdbc.url}
此時,我感覺這${jdbc.url}這些讀取jdbc.properties文件的屬性的值好像都有問題。經過查閱資料,終於在一篇文章上找到了問題在哪。
引用鏈接:https://blog.csdn.net/zcl1199/article/details/51172420
原來這些報錯信息是指將${jdbc.driver}這些值當做了字符串,所以報錯信息裏直接寫的${jdbc.driver}而不是解析之後的值。
解決方法
通過以上資料我們知道了是由於sqlSessionFactory的加載順序在PropertyPlaceholderConfigurer之前,導致了sqlSessionFactory使用的jdbc配置信息全都未解析。
我本來的配置文件如下:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 1、數據源 DriverManagerDataSource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 2.mybatis的SqlSession的工廠:SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 定義數據源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 別名包 -->
<property name="typeAliasesPackage" value="com.manager.entity"/>
<!-- mapper.xml -->
<property name="mapperLocations" value="classpath:mybatis/mappers/*.xml"/>
</bean>
<!-- 3.mybatis自動掃描加載sql映射文件:MapperScannerConfigurer -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 掃描mapper包 -->
<property name="basePackage" value="com.manager.mapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
<!-- 4.事物管理:DataSourceTransactionManager -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 5.使用聲明事物 -->
<tx:annotation-driven transaction-manager="txManager"/>
</beans>
修改後的配置文件如下:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 1、數據源 DriverManagerDataSource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 2.mybatis的SqlSession的工廠:SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 定義數據源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 別名包 -->
<property name="typeAliasesPackage" value="com.manager.entity"/>
<!-- mapper.xml -->
<property name="mapperLocations" value="classpath:mybatis/mappers/*.xml"/>
</bean>
<!-- 3.mybatis自動掃描加載sql映射文件:MapperScannerConfigurer -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 掃描mapper包 -->
<property name="basePackage" value="com.manager.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
<!-- 4.事物管理:DataSourceTransactionManager -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 5.使用聲明事物 -->
<tx:annotation-driven transaction-manager="txManager"/>
</beans>
改動就是將sqlSessionFactory注入改爲sqlSessionFactoryBeanName注入,注意要將後面的ref屬性改爲value。