Spring 上下文:属性占位符不';无法解析引用

Spring 上下文:属性占位符不';无法解析引用,spring,mybatis,Spring,Mybatis,我在类路径的根目录下有一个applicationContext.xml文件: <context:annotation-config /> <context:property-placeholder location="classpath:props/datasource.properties" /> <bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource"

我在类路径的根目录下有一个
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" />
我有一个spring托管测试,我声明通过下一个注释使用前面提到的applicationContext.xml:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
当我调用测试方法时,我从spring得到下一个错误:

org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class '${jdbc.driverclass}'
据我所知,sping没有解析对jdbc.driverclass的引用。 我做错了什么

PS:我正在使用Spring3.2.3.RELEASE

**

编辑 **

问题可能出在
MapperScannerConfigure
中。它是一个
BeanDefinitionRegistryPostProcessor
,正如Javadoc所说:

标准BeanFactory后处理器SPI的扩展, 允许注册更多的bean定义 常规BeanFactory后处理器检测开始之前

因此,
MapperScannerConfiguration
通过sqlSessionFactory使用
BeanFacoryPostProcessor
(负责
)实例化数据源对象尚未使用。 因此,我的问题转化为如何从
BeanDefinitionRegistryPostProcessor
MapperScannerConfigure
)对
BeanFacoryPostProcessor
进行重新排序

断然的 经过几个小时的调查,我找到了解决办法:


正如我前面所说的
MapperScannerConfigure
是一个
BeanDefinitionRegistryPostProcessor
,它在
BeanFactoryPostProcessor
之前启动,负责
。因此,在创建MapperScannerConfigure期间,不会解析对外部属性的引用。在这种情况下,我们必须将数据源的创建推迟到应用
BeanFactoryPostProcessor
之后。我们可以通过以下几种方式实现:

  • MapperScannerConfigure
    中删除
    p:sqlSessionFactory ref=“sqlSessionFactory”
    。在这种情况下,数据源对象不会在
    MapperScannerConfiguration
    之前创建,而是在负责
    BeanFactoryPostProcessor
    之后创建。如果applicationContext中有多个sqlSessionFactory,则可能会出现一些问题
  • 在高于1.0.2的mybatis spring模块版本中,可以设置
    sqlSessionFactoryBeanName
    而不是
    sqlSessionFactory
    。它有助于使用
    BeanFactoryPostProcessor
    解决PropertyPlaceHolder问题。这是解决mybatis spring中描述的此问题的推荐方法

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

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location">
        <value>classpath:database.properties</value>
    </property>
    <property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>

classpath:database.properties

我也在使用Spring3.2.3.RELEASE。我知道这篇文章已经有4个多月的历史了,但我想也许有人会觉得它有用

缩写:加载:BeanDefinitionRegistryPostProcessor实现的正确方法是什么

扩展表单:是否有方法在创建任何bean之前加载BeanDefinitionRegistryPostProcessor。如果您查看javadoc:

对标准{@link BeanFactoryPostProcessor}SPI的扩展,允许 在正则表达式之前注册更多的bean定义 BeanFactory后处理器检测开始


因此,它意味着在创建bean定义时加载,但在创建任何bean之前加载。如果我们只是在应用程序xml中创建一个普通的bean,那么它首先就无法实现拥有这个bean的目的

Spring上下文配置中是否有其他
属性PlaceHolderConfigure
?当然不是,我通过在setLocations方法中设置断点来检查它:只有在我尝试使用属性位置的前导
/
时才会调用它:
location=“classpath:/props/datasource.properties”
我也有同样的问题,我只是删除了autoWire=“byName”",属性文件工作。@maks you ripper。我遇到了同样的问题,即我一添加
MapperScannerConfigure
它就会破坏我的属性占位符。当查看代码时,我发现它实现了
BeanDefinitionRegistryPostProcessor
,这使我相信它是原因和最终原因mately找到了你的问题。回答你自己的问题,伙计!这正是必要的解决方案:)
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location">
        <value>classpath:database.properties</value>
    </property>
    <property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>