1. 程式人生 > >spring中mybatis配置資料來源讀取不到properties屬性檔案的問題

spring中mybatis配置資料來源讀取不到properties屬性檔案的問題

<bean id="tomcatJdbcDataSourceFactory" class="com.qunar.db.resource.impl.TomcatJdbcDataSourceFactory"/>    
<bean id="dataSource" class="com.qunar.db.resource.RWDelegatorDataSource">
 <constructor-arg index="0"  type="java.lang.String" value="${dictDataSource.jdbc.usernameSpace}"/>  
<constructor-arg index="1"  type="java.lang.String" value="${dictDataSource.jdbc.username}"/>  

<constructor-arg index="2"  type="java.lang.String" value="${dictDataSource.jdbc.password}"/> 
<constructor-arg index="3"  type="java.lang.String" value="${dictDataSource.jdbc.db_name}"/> 
<constructor-arg index="4"  type="int" value="20"/> 
<constructor-arg index="5"  type="int" value="50"/>  

<constructor-arg index="6"  type="java.lang.String" value="?useUnicode=true&amp;characterEncoding=UTF-8&amp;allowMultiQueries=true"/>  
<constructor-arg index="7"  type="boolean" value="true"/> 
<constructor-arg index="8"  ref="tomcatJdbcDataSourceFactory"/>
</bean>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  

    <property name="dataSource" ref="dataSource"/>  
    <property name="configLocation" value="classpath:mybatis-config.xml"/>  
       <property name="mapperLocations" value="classpath*:com.anly.portal.*.mapper/*Mapper.xml" />    
</bean>  
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
       <property name="basePackage" value="com.anly.portal.*.mapper"/>  
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>  
</bean>  
 此時,啟動會報異常,${jdbc.driver}這樣的表示式獲取不到properties裡面的值,因為MapperScannerConigurer實際是在解析載入bean定義階段的,這個時候要是設定sqlSessionFactory的話,會導致提前初始化一些類,這個時候,PropertyPlaceholderConfigurer還沒來得及替換定義中的變數,導致把表示式當作字串複製了,解決的辦法如下:

修改為

  <bean id="tomcatJdbcDataSourceFactory" class="com.qunar.db.resource.impl.TomcatJdbcDataSourceFactory"/>    
    <bean id="dataSource" class="com.qunar.db.resource.RWDelegatorDataSource">
 <constructor-arg index="0"  type="java.lang.String" value="${dictDataSource.jdbc.usernameSpace}"/>  
     <constructor-arg index="1"  type="java.lang.String" value="${dictDataSource.jdbc.username}"/>  
     <constructor-arg index="2"  type="java.lang.String" value="${dictDataSource.jdbc.password}"/> 
     <constructor-arg index="3"  type="java.lang.String" value="${dictDataSource.jdbc.db_name}"/> 
     <constructor-arg index="4"  type="int" value="20"/> 
     <constructor-arg index="5"  type="int" value="50"/>  
     <constructor-arg index="6"  type="java.lang.String" value="?useUnicode=true&amp;characterEncoding=UTF-8&amp;allowMultiQueries=true"/>  
     <constructor-arg index="7"  type="boolean" value="true"/> 
     <constructor-arg index="8"  ref="tomcatJdbcDataSourceFactory"/>
</bean>
 <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="mapperLocations" value="classpath:mappers/*.xml"/>
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.qunar.flight.interb2b.airport.dict.dao" />
        <property name="sqlSessionFactoryBeanName" value="sessionFactory" />
    </bean>

原理:使用sqlSessionFactoryBeanName注入,不會立即初始化sqlSessionFactory, 所以不會引發提前初始化問題,同時還應注意在配置org.mybatis.spring.SqlSessionFactoryBean
這個Bean時,id不能為sqlSessionFactory,如果為這樣的話會導致MapperScannerConigurer在bean定義載入時,載入PropertyPlaceholderConfigurer還沒來得及替換定義中的變數