【问题标题】:PropertyPlaceholderConfigurer for reading property files and databasePropertyPlaceholderConfigurer 用于读取属性文件和数据库
【发布时间】:2015-02-17 14:58:53
【问题描述】:

我正在尝试创建两个PropertyPlaceholderConfigurer,一个用于访问属性文件,另一个用于访问数据库...代码如下

  <bean id="otherPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="ignoreUnresolvablePlaceholders" value="true"/>
        <property name="properties">
        <bean class="org.apache.commons.configuration.ConfigurationConverter" factory-method="getProperties">
            <constructor-arg>
                <bean class="org.apache.commons.configuration.DatabaseConfiguration">
                    <constructor-arg ref="myDataSource"/>
                     <constructor-arg value="dbo.APPLICATIONPROPERTIES"/>
                     <constructor-arg value="NAME"/>
                   <constructor-arg value="VALUE"/>
                </bean>
            </constructor-arg>
        </bean>
        </property>
    </bean>

  <bean id="propertyConfigurer" class="com.fexco.wuams.util.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:database.properties</value>
            </list>         
        </property>
    </bean>

我有以下ComboPooledDataSource

<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${driver}"/>
    <property name="jdbcUrl" value="${url}"/>
    <property name="user" value="${username}"/>
    <property name="password" value="${password}"/>
    <property name="initialPoolSize" value="5"/>
    <property name="minPoolSize" value="5"/>
    <property name="maxPoolSize" value="5"/>
    <property name="maxIdleTime" value="1200"/>
    <property name="idleConnectionTestPeriod" value="300"/>
  </bean>

这对我的应用程序的其余部分非常有效,除非我尝试将它用于我的 bean id="otherPropertyConfigurer"... 我收到以下错误

Caused by: org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'driverClass' threw exception; nested exception is java.beans.PropertyVetoException: Could not locate driver class with name '${jdbc.driverClassName}'.
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:104)
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:59)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1275)
    ... 72 more

如果我在ComboPooledDataSource 中硬编码数据库变量(例如,将${jdbc.driverClassName} 更改为net.sourceforge.jtds.jdbc.Driver 一切正常,但由于某种原因,当我添加otherPropertyConfigurer 时,我原来的propertyConfigurer 不起作用

有人对如何解决这个问题有任何想法吗?

【问题讨论】:

    标签: java sql-server spring


    【解决方案1】:

    我讨厌成为坏消息的裸露者,但是你想要实现的,Spring 物理上做不到。

    因为 Springs PropertyPlaceholderConfigurer 类作为 beanPostProcessors,它在创建任何其他 bean 之前创建和调用这些 bean。但是,如果您有多个 PropertyPlaceholderConfigurer,其中一个依赖于另一个,Spring 将始终在调用其中任何一个之前完全创建两个实例。因此,您在 myDataSource 中的占位符永远无法解析。

    this question 中更好地描述了该问题。

    此问题的最佳解决方案通常是停止使用数据库进行配置管理。我发现最好使用一个简单的配置文件,它可以根据环境进行修改,并托管在您的部署容器中。

    【讨论】:

      【解决方案2】:

      正如 ConMan 建议的那样,这不能按照我在上面的问题中解释的方式完成。但我已经设法解决了这个问题,而是使用以下代码将属性 (propertiesFromDB) 传递到类中

      <bean id="propertiesFromDB"
              class="org.springframework.beans.factory.config.PropertiesFactoryBean">
              <property name="properties" ref="configurationFactoryBean" />
          </bean>
      
          <bean name="configurationFactoryBean"
              class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
              <property name="configurations" ref="applicationProperties" />
          </bean>
      
      
          <bean id="applicationProperties" class="org.apache.commons.configuration.DatabaseConfiguration">
              <constructor-arg type="javax.sql.DataSource" ref="myDataSource" />
              <constructor-arg index="1" value="dbo.APPLICATIONPROPERTIES" />
              <constructor-arg index="2" value="NAME" />
              <constructor-arg index="3" value="VALUE" />
          </bean>
      

      然后我可以使用getProperty() 方法并传递NAME 变量来获取我想要的任何属性

      【讨论】:

        猜你喜欢
        • 2018-07-21
        • 1970-01-01
        • 2014-10-18
        • 2011-08-23
        • 1970-01-01
        • 2013-06-30
        • 2012-02-09
        • 2012-06-06
        • 1970-01-01
        相关资源
        最近更新 更多