在學習mybatis與spring整合是,想從外部引用一個db.properties數據庫配置文件,在配置文件中使用占位符進行引用,如下:
1 <context:property-placeholder location="classpath:db.properties" /> 2 <bean id="dataSource" 3 class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 4 <property name="url" value="${jdbcUrl}"></property> 5 <property name="driverClassName" value="${driverClass}"></property> 6 <property name="username" value="${username}"></property> 7 <property name="password" value="${password}"></property> 8 </bean>
但是卻拋出Exception:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'driverClassName' threw exception; nested exception is java.lang.IllegalStateException: Could not load JDBC driver class [${driverClass}]
這是因為MapperScannerConigurer實際是在解析加載bean定義階段的,這個時候要是設置sqlSessionFactory的話,會導致提前初始化一些類,這個時候,PropertyPlaceholderConfigurer還沒來得及替換定義中的變量,導致把表達式當作字符串復制了,解決的辦法如下:
方法一:將<property name="sqlSessionFactory" ref="sqlSessionFactory"/>改為
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
使用sqlSessionFactoryBeanName注入,不會立即初始化sqlSessionFactory, 所以不會引發提前初始化問題。
方法二:直接刪掉<property name="sqlSessionFactory" ref="sqlSessionFactory"/>,但是必須在文件中配置一個id為sqlSessionFactory的 sqlSessionFactoryBean,因為在不配置時Scanner會自動去配置文件中尋找同名的bean。如:
1 <!-- 2.創建sqlSessionFactory:SqlSessionFactoryBean --> 2 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 3 <!-- 2-1.為sessionFactory附上數據源 --> 4 <property name="dataSource" ref="dataSource"></property> 5 <!-- 2-2.設置掃描別名的包,一般設置實體類所在包 等價於原先package標簽 --> 6 <property name="typeAliasesPackage" value="cn.edu.mybatis.entities"></property> 7 </bean>