`

PropertyPlaceholderConfigurer模式从properties加载数据源参数失败的解决方案

阅读更多

        今天关注项目中的各配置文件参数设置是否恰当,然后就发现数据源是直接把各参数配置在applicationContent.xml文件当中,同时项目中其它模块又用到了properties配置文件引入属性值的做法,于是就想把数据源配置的参数也迁移到properties配置文件中来,便于以后的修改。

 

        由于使用的是springmvc框架(spring3.1.1+mybatis3.1.1+mybatis-spring-1.1.1),所以就在applicationContent.xml中配置PropertyPlaceholderConfigurer来加载properties配置文件,谁想这种以前在项目中应用很好使的方式今天怎么也通不过,配置完成,重新部署后就报如下错误:

 

严重: 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版本问题,就搜索了一下“spring3  PropertyPlaceholderConfigurer”,结果发现还真有类似的提问,只不过比我问的更准确,一下就把问题定位到了问题的根源-------mybatis下的MapperScannerConfigurer扫描模式造成了bean的加载顺序改变从而使得PropertyPlaceholderConfigurer无法正常加载。

 

       具体说来就是,myabatis使用MapperScannerConfigurer扫描模式后他会优先于PropertyPlaceholderConfigurer执行,所以这个时候,${cpool.checkoutTimeout}还没有被properties文件里面的值所替换,所以出现TypeMismatchException,然后就异常了

 

       知道了异常原因所在,那么问题解决结会快一些了,于是按照相关搜索,查阅下面的帖子,基本找到解决方案:

http://www.oschina.net/question/188964_32305

 

     当然,毕竟不是一模一样的错误,还是需要做一些调整,下面把调整的内容列出来,希望对同样问题的朋友有帮助,请留意标红的地方:

 

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	<property name="locations">
		<list>
			<value>classpath:xxxxx.properties</value>
		</list>
	</property>
</bean>
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClassName}" />
		<property name="jdbcUrl" value="${jdbc.url}" />
		<property name="user" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="autoCommitOnClose" value="true"/>
		<property name="checkoutTimeout" value="${cpool.checkoutTimeout}"/>
</bean>

<!--只要下面bean的id不叫sqlSessionFactory,就成-->

<bean id="ysqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="configLocation" value="classpath:sqlMapConfig.xml"/>
    <property name="mapperLocations" >
        <list>
	     <value>classpath:com/xxx/xxx/xxx/*.xml</value>
	     <value>classpath:com/xxx/xxx/xxx/*.xml</value>
        </list>
     </property>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
	<constructor-arg index="0" ref="ysqlSessionFactory"></constructor-arg>
	<constructor-arg index="1" value="BATCH"></constructor-arg>
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
	<property name="basePackage" value="com.xxx.xxx.dao,com.xxx.xxx.xxx.dao,com.xxx.xxx.xxx.dao"/>
         <!--核心就是添加下面一句。后面那个属性是value,不是ref,切记-->
	<property name="sqlSessionFactoryBeanName" value="ysqlSessionFactory" />
</bean>

 

 

在3.1.1版本中配置的时候提供了以下属性值关联:

 

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  

     <property name="basePackage" value="com.xxxx.dal.mapper" /> 

     <property name="sqlSessionFactoryBeanName" value="ysSqlSessionFactory" />

     <!--<property name="sqlSessionFactory" ref="ysSqlSessionFactory"></property> -->

</bean>

改用sqlSessionFactoryBeanName注入就没有问题(不要使用sqlSessionFactory属性注入,使用sqlSessionFactoryBeanName注入),因为这时不会立即初始化sqlSessionFactory,传入的只是名字,非bean,所以不会引发提前初始化问题。。

 

 

最后再备注两个链接:

PropertyPlaceholderConfigurer介绍和应用

http://www.cnblogs.com/yl2755/archive/2012/05/06/2486752.html

Mybatis学习系列:

http://legend2011.blog.51cto.com/3018495/908956

分享到:
评论
1 楼 di1984HIT 2014-10-22  
不错,谢谢啦!!

相关推荐

Global site tag (gtag.js) - Google Analytics