context:property-placeholder不解析引用

mak*_*aks 8 spring mybatis

applicationContext.xml在classpath的根目录下有下一个文件:

<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" />
Run Code Online (Sandbox Code Playgroud)

props/datasource.properties 也存在于classpath的根目录中,内容如下:

jdbc.url=myjdbcurl
jdbc.driverclass=myClass
jdbc.username=myUserName
jdbc.password=myPassword
Run Code Online (Sandbox Code Playgroud)

我有一个spring托管测试,我声明通过下一个注释使用前面提到的applicationContext.xml:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
Run Code Online (Sandbox Code Playgroud)

当我调用测试方法时,我从spring获得下一个错误:

org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class '${jdbc.driverclass}'
Run Code Online (Sandbox Code Playgroud)

据我所知,sping没有解析对jdbc.driverclass的引用.我做错了什么?

PS:我正在使用spring 3.2.3.RELEASE

**

编辑

**

也许问题可能在于MapperScannerConfigurer.这是一个BeanDefinitionRegistryPostProcessor和Javadoc说:

扩展到标准BeanFactoryPostProcessor SPI,允许常规BeanFactoryPostProcessor检测开始之前注册其他bean定义

因此,MapperScannerConfigurer通过sqlSessionFactory实例化数据源对象BeanFacoryPostProcessor(负责<context:property-placeholder/>)尚未使用.所以我的问题转变为如何BeanFacoryPostProcessor<context:property-placeholder/>BeanDefinitionRegistryPostProcessor(MapperScannerConfigurer)重新排序?

解决

经过几个小时的调查后,我找到了解决方案:


正如我之前所说,MapperScannerConfigurerBeanDefinitionRegistryPostProcessor之前的火灾BeanFactoryPostProcessor负责<context:property-placeholder/>.因此,在创建MapperScannerConfigurer期间,不会解析对外部属性的引用.在这种情况下,我们必须将数据源的创建推迟到BeanFactoryPostProcessor应用之后的时间.我们可以通过几种方式做到这一点:

  • p:sqlSessionFactory-ref="sqlSessionFactory"从中移除MapperScannerConfigurer.在这种情况下,数据源对象不会在之前创建MapperScannerConfigurer,但在BeanFactoryPostProcessor此之后负责<context:property-placeholder/>.如果你在applicationContext中有多个sqlSessionFactory,那可能会遇到一些麻烦
  • 在高于1.0.2的mybatis-spring模块版本中,有可能设置sqlSessionFactoryBeanName而不是sqlSessionFactory.它有助于解决PropertyPlaceHolder问题BeanFactoryPostProcessor.这是解决mybatis-spring doc中描述的这个问题的推荐方法

Dan*_*Dan 0

我遇到了同样的问题,并看到了这篇文章,但我无法像 makes 那样解决它。最终对我有用的是将ignoreUnresolvablePlaceholders属性值设置为true。

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location">
        <value>classpath:database.properties</value>
    </property>
    <property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
Run Code Online (Sandbox Code Playgroud)

我也在使用 Spring 3.2.3.RELEASE。我意识到这篇文章已经有 4 个多月了,但我想有人可能会觉得它有用。