spring mybatis不能使用變量連接數據庫

問題描述:

    springMVC集成mybatis,通過c3p0連接數據庫。將數據庫信息寫入到了jdbc.properties文件中,配置數據源時使用${}獲取變量,啓動後報錯,提示java.lang.ClassNotFoundException: ${driverClassName}    具體配置如下:

 



解決辦法:

    方法一: 修改mybatis的MapperScannerConfigurer配置,不設置其sqlSessionFactory屬性。但需要保證一定要有sqlSessionFactory這個bean。

   方法二:設置其sqlSessionFactoryBeanName屬性,因爲這時不會立即初始化sqlSessionFactory,傳入的只是名字,所以不會引發提前初始化問題。(適用於spring 3.1.1以上版本)

分析原因:

  1.首先查詢源代碼中PropertiesLoaderUtils.fillProperties()方法,經調試發現jdbc.property的鍵值對已被正確讀取。


  2.然後查詢初始化數據源MyDataSource這個bean組件的代碼,發現爲其屬性賦值時,值中的字符串變量沒有被替換。具體參考AbstractAutowireCapableBeanFactory.java的applyPropertyValues()方法


 3.此時懷疑加載MyDataSource這個bean太早了,應該是早於加載ProPertyConfiguer這個bean,導致的無法替換變量值

  4.調試源代碼AbstractBeanFactory.java的doGetBean()方法,發現首先加載的是MapperScannerConfigurer,然後是sqlSessionFactory和MyDataSource,後來才加載ProPertyConfiguer這個Bean.


 5.此時問題已經清晰了,因爲首先加載MapperScannerConfigurer,而爲其設置屬性時用到了MyDataSource所以,導致其加載早於了ProPertyConfiguer。


結論:

  spring裏使用org.mybatis.spring.mapper.MapperScannerConfigurer 進行自動掃描的時候,設置了sqlSessionFactory 的話,可能會導致PropertyPlaceholderConfigurer失效,也就是用${jdbc.username}這樣之類的表達式,將無法 獲取到properties文件裏的內容。 導致這一原因是因爲,MapperScannerConigurer實際是在解析加載bean定義階段的,這個時候要是設置sqlSessionFactory的話,會導致提前初始化一些類,這個時候,PropertyPlaceholderConfigurer還沒來得及替 換定義中的變量,導致把表達式當作字符串複製了。

發佈了6 篇原創文章 · 獲贊 8 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章