applicationContext.xml
クラスパスのルートに次のファイルがあります。
<context:annotation-config />
<context:property-placeholder location="classpath:props/datasource.properties" />
<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource"
p:username="${jdbc.username}"
p:password="${jdbc.password}"
p:url="${jdbc.url}"
p:driverClassName="${jdbc.driverclass}"
p:validationQuery="SELECT sysdate FROM dual" />
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
p:dataSource-ref="datasource"
p:mapperLocations="classpath:mappers/*-mapper.xml" />
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="datasource" />
<bean id="mappeScannerConfigurere" class="org.mybatis.spring.mapper.MapperScannerConfigurer"
p:sqlSessionFactory-ref="sqlSessionFactory"
p:basePackage="com.mypackage" />
props/datasource.properties
次のような内容のクラスパスのルートにも存在します。
jdbc.url=myjdbcurl
jdbc.driverclass=myClass
jdbc.username=myUserName
jdbc.password=myPassword
次の注釈を介して前述の applicationContext.xml を使用することを宣言するスプリング マネージド テストがあります。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
テストメソッドを呼び出すと、春から次のエラーが発生します:
org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class '${jdbc.driverclass}'
私が理解しているように、spingはjdbc.driverclassへの参照を解決しませんでした。私は何を間違えましたか?
PS:春の 3.2.3.RELEASE を使用しています
**
編集
**
おそらく、問題は にある可能性がありますMapperScannerConfigurer
。BeanDefinitionRegistryPostProcessor
Javadocが言うように、それはおよびです:
標準の BeanFactoryPostProcessor SPI の拡張。通常の BeanFactoryPostProcessor 検出が開始される前に、さらに Bean 定義を登録できます 。
そのため、 sqlSessionFactoryMapperScannerConfigurer
を介してデータソース オブジェクトをインスタンス化しますBeanFacoryPostProcessor
(を担当する<context:property-placeholder/>
) は使用されていません。私の質問は、 and ( )BeanFacoryPostProcessor
から並べ替える方法に変わりますか?<context:property-placeholder/>
BeanDefinitionRegistryPostProcessor
MapperScannerConfigurer
解決済み
数時間の調査の後、私は解決策を見つけました:
先に述べたようMapperScannerConfigurer
に、 は のBeanDefinitionRegistryPostProcessor
前に発生しBeanFactoryPostProcessor
、 は の責任を負い<context:property-placeholder/>
ます。そのため、MapperScannerConfigurer の作成中、外部プロパティへの参照は解決されません。この場合、データソースの作成をBeanFactoryPostProcessor
適用後まで延期する必要があります。これにはいくつかの方法があります。
- から削除
p:sqlSessionFactory-ref="sqlSessionFactory"
しMapperScannerConfigurer
ます。この場合、データソース オブジェクトは の前に作成されるMapperScannerConfigurer
のではなく、後で作成さBeanFactoryPostProcessor
れ<context:property-placeholder/>
ます。applicationContext に複数の sqlSessionFactory がある場合、いくつかの問題が発生する可能性があります - mybatis-spring モジュールのバージョン 1.0.2 以降では、 の
sqlSessionFactoryBeanName
代わりに設定する可能性がありsqlSessionFactory
ます。で PropertyPlaceHolder の問題を解決するのに役立ちますBeanFactoryPostProcessor
。mybatis-spring docに記載されているこの問題を解決するための推奨される方法です。