spring mybatis解决application.properties注入变量问题

问题描述

在使用spring mybatis的时候配置数据源dataSource,为了修改方便,新建了一个application.properties其中保存了jdbc.url,jdbc.username等信息。
这样在dataSource定义的时候 可以直接使用jdbc.url这些变量。使用方式为 ${jdbc.url},可是配置完成之后,启动程序报错,
报错原因是application中的jdbc.url变量没有注入到datasource中。

严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.mybatis.spring.mapper.MapperScannerConfigurer#0' defined in ServletContext resource [/****/application-context.xml]: Initialization of bean failed;

nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in ServletContext resource[/***/application-context.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 ServletContext resource [/*****/application-context.xml]: Initialization of bean failed;

nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'Java.lang.String' to required type 'int' for property 'checkoutTimeout';

nested exception is java.lang.NumberFormatException: For input string: "${cpool.checkoutTimeout}"


问题原因

在spring里使用org.mybatis.spring.mapper.MapperScannerConfigurer 进行自动扫描的时候,设置了sqlSessionFactory 的话,可能会导致PropertyPlaceholderConfigurer失效,也就是用${jdbc.username}这样之类的表达式,将无法获取到properties文件里的内容。

导致这一原因是因为,MapperScannerConigurer在spring启动过程中提前加载,,这个时候要是引用sqlSessionFactory的话,会导致sqlSessionFactory 提前加载,而此时PropertyPlaceholderConfigurer这个类还没有加载完成,也就无法完成表达式=》值的替换工作。自然sqlSessionFactory属性配置的表达式还没有替换成properties文件相应的值, sqlSessionFactory就被迫初始化了,所以在之后访问数据的时候,因为连不上数据库,就报错。

解决方法

1.MapperScannerConigurer如果是引用了sqlSessionFactory bean,则注释掉该行,

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="mybatis_test.client" />
    <property name="markerInterface" value="mybatis_test.client.SuperMapper" />
    <!-- <property name="sqlSessionFactory" ref="sqlSessionFactory" /> -->
</bean>

2.也可以添加如下一行配置。此时在MapperScannerConfigurer初始化的的时候只是传了一个beanName非bean,所以不会引发提前初始化问题。但是这里设置的beanName一定要和定义的Bean sessionFactory的id一样
代码如下:

<!-- <property name="sqlSessionFactory" ref="sqlSessionFactory" /> -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />

环境配置

maven配置

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.2.7</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.2.2</version>
</dependency>
<!-- spring 核心4.1.4 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.1.4.RELEASE</version>
</dependency>

参考

参考oschina上的解决方法

PropertyPlaceholderConfigurer介绍和应用:http://www.cnblogs.com/yl2755/archive/2012/05/06/2486752.html

spring引入properties中的变量

通过配置

<!-- 当需要多个配置文件的时候,将ignore-unresolvable设置为"true"- -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:application.properties" />
原文地址:https://www.cnblogs.com/chenny3/p/10226179.html